home *** CD-ROM | disk | FTP | other *** search
/ Internet Tools (InfoMagic) / Internet Tools.iso / news / readers / nnmvs / distrib.cntl.v2r4.Z / distrib.cntl.v2r4
Text File  |  1995-04-24  |  2MB  |  26,762 lines

  1. //JOBNAME  JOB ACCOUNT,'NAME'                                                   
  2. //*------------------------------------------------------------------*/         
  3. //*                                                                  */         
  4. //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5. //*                                                                  */         
  6. //* This software is provided on an "AS IS" basis.  All warranties,  */         
  7. //* including the implied warranties of merchantability and fitness, */         
  8. //* are expressly denied.                                            */         
  9. //*                                                                  */         
  10. //* Provided this copyright notice is included, this software may    */         
  11. //* be freely distributed and not offered for sale.                  */         
  12. //*                                                                  */         
  13. //* Changes or modifications may be made and used only by the maker  */         
  14. //* of same, and not further distributed.  Such modifications should */         
  15. //* be mailed to the author for consideration for addition to the    */         
  16. //* software and incorporation in subsequent releases.               */         
  17. //*                                                                  */         
  18. //*------------------------------------------------------------------*/         
  19. //*                                                                             
  20. //* NNMVS - NNTP Client News Reader for MVS/ISPF - Version 2 Release 4          
  21. //*                                                                             
  22. //* Author:  Steve Bacher <seb1525@mvs.draper.com>                              
  23. //*                                                                             
  24. //* Date:  June, 1992                                                           
  25. //*                                                                             
  26. //*--------------------------------------------------------------------         
  27. //*                                                                             
  28. //* This job creates the NNMVS distribution libraries (PDS's).                  
  29. //*                                                                             
  30. //* Run this JCL to create the PDS's, after customizing to suit.                
  31. //* (Obviously, put in a good JOB statement first.)                             
  32. //* To customize the JCL, change the defaults on the //NNLOAD PROC              
  33. //* statement to your liking, particularly the PREFIX default.                  
  34. //* You might also want to change the final qualifiers of the PDS's             
  35. //* created - to do this, find the // EXEC NNLOAD statements and                
  36. //* change the value of the TO parameter.                                       
  37. //*                                                                             
  38. //* See the $$README file (of the CNTL PDS, first in this stream)               
  39. //* for the rest of the installation instructions.                              
  40. //*                                                                             
  41. //NNLOAD  PROC CLS='*',BS='6160',U='3380',V='',                                 
  42. //             TRK1='30',TRK2='10',DIR='35',RLSE='RLSE',                        
  43. //             PREFIX='NNMVS.INSTALL.'                                          
  44. //*                                                                             
  45. //IEBUPDTE EXEC PGM=IEBUPDTE,PARM=NEW                                           
  46. //SYSPRINT DD   SYSOUT=&CLS                                                     
  47. //SYSUT2   DD   DISP=(NEW,CATLG,DELETE),DSN=&PREFIX.&TO,                        
  48. //         DCB=(RECFM=FB,LRECL=80,BLKSIZE=&BS),                                 
  49. //         SPACE=(TRK,(&TRK1,&TRK2,&DIR),&RLSE),UNIT=&U,VOL=SER=&V              
  50. //*                                                                             
  51. //         PEND                                                                 
  52. //CNTL     EXEC NNLOAD,TRK1='5',TO='CNTL'                                       
  53. //SYSIN    DD DATA,DLM='?!'                                                     
  54. ./   ADD NAME=$$README,SSI=012A0028                                             
  55.                                                                                 
  56. ------------------------------------------------------------------------        
  57.                                                                                 
  58.  Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992                  
  59.                                                                                 
  60.  SAS enhancements copyright (c) 1992 SAS Institute, Inc.                        
  61.                                                                                 
  62.  This software is provided on an "AS IS" basis.  All warranties,                
  63.  including the implied warranties of merchantability and fitness,               
  64.  are expressly denied.                                                          
  65.                                                                                 
  66.  Provided this copyright notice is included, this software may                  
  67.  be freely distributed and not offered for sale.                                
  68.                                                                                 
  69.  Changes or modifications may be made and used only by the maker                
  70.  of same, and not further distributed.  Such modifications should               
  71.  be mailed to the author for consideration for addition to the                  
  72.  software and incorporation in subsequent releases.                             
  73.                                                                                 
  74. ------------------------------------------------------------------------        
  75.                                                                                 
  76.  MVS NNTP News Reader - Version 2 Release 4                                     
  77.                                                                                 
  78.  Author:          Steve Bacher <seb1525@mvs.draper.com>                         
  79.  Enhancements by: Dale Ingold  <snoddi@mvs.sas.com>                             
  80.                                                                                 
  81. ------------------------------------------------------------------------        
  82.                                                                                 
  83.  New Features and Changes in member $CHANGES of the distribution.               
  84.                                                                                 
  85. ------------------------------------------------------------------------        
  86.                                                                                 
  87.  Contents of PDS's belonging to NNMVS distribution:                             
  88.                                                                                 
  89.  Member     PDS Type    Description                                             
  90.                                                                                 
  91.  $$README   CNTL        This file                                               
  92.  $CHANGES   CNTL        New features and changes                                
  93.  $MISC      CNTL        Miscellaneous gotchas and installation notes            
  94.  ALLOAD     CNTL        JCL to allocate NNMVS load library                      
  95.  AUTH       CNTL        Sample server authorization file                        
  96.  COMPILE    CNTL        JCL to compile and link C source                        
  97.  GRAMMAR    CNTL        Description of NNMVS batch expression syntax            
  98.  HELP       CNTL        Description of NNMVS batch language                     
  99.  NNMVS      CNTL        JCL to run NNMVS in batch                               
  100.  NNMVSHLP   CNTL        TSO HELP for the NNMVSP version of the exec             
  101.  NNMFIUCV   CLIST       Exec to check for multiple socket applications          
  102.  NNMVS      CLIST       Exec by which users invoke the news reader              
  103.  NNMVSC     CLIST       CLIST by which users invoke the news reader             
  104.  NNMVSL     CLIST       CLIST to run multiple-news-server ISPF dialog           
  105.  NNMVSP     CLIST       Exec using XPROC to parse CLIST-style parms             
  106.  NNMMAIL    CLIST       Exec called by news reader to send mail                 
  107.  NNM...     PANEL       ISPF regular panels                                     
  108.  TNNM...    PANEL       ISPF tutorial panels                                    
  109.  NN...      H           C headers for compilation                               
  110.  NNM...     C           C source for compilation                                
  111.                                                                                 
  112. --------------------------------------------------------------------            
  113.                                                                                 
  114.  Directions:                                                                    
  115.                                                                                 
  116.  Assuming the PDS's have been created:                                          
  117.                                                                                 
  118.  1. Customize the ALLOAD and COMPILE JCL members to reflect your                
  119.  local conventions.  Note:  If you intend to place the executable into          
  120.  an existing library, you can suppress that part of the ALLOAD JCL.             
  121.  The name of the data set created must match across both members.               
  122.                                                                                 
  123.  2. Customize the NNUSER header file as shown by the comments therein.          
  124.  Note in particular the defines for your TCP/IP and your C compiler.            
  125.  There are changes to the linkedit JCL that are related to these.               
  126.                                                                                 
  127.  3. Choose which exec you want to use:                                          
  128.                                                                                 
  129.     NNMVS - the traditional REXX exec, not much parameter passing               
  130.     NNMVSP - REXX exec that uses XPROC to parse CLIST-style parms               
  131.     NNMVSC - CLIST that accepts CLIST-style parameters                          
  132.                                                                                 
  133.  If you don't have XPROC (the utility that allows a REXX exec to parse          
  134.  CLIST-style parameters), you can get it from the same place that you           
  135.  got NNMVS.  I highly recommend that you do so if you do a lot of               
  136.  conversion from CLIST to REXX.                                                 
  137.                                                                                 
  138.  If you really can't or won't get XPROC, you can use the CLIST, but             
  139.  keep in mind that there are some things the CLIST just can't do that           
  140.  the REXX exec can.  Refer to the comments therein for more details.            
  141.                                                                                 
  142.  Customize whichever of the above you pick to define the names of the           
  143.  MVS libraries to contain the panel and load library members.  The load         
  144.  library must be the one specified in the ALLOAD JCL, if you are                
  145.  creating it anew.  Observe the comments relating to the use of LIBDEF          
  146.  and ISPF APPLIDs.                                                              
  147.                                                                                 
  148.  Note that if you install one of the REXX execs, you must also install          
  149.  the NNMFIUCV exec in the same library.  This exec implements a crude           
  150.  check for an existing TCP/IP socket application (e.g. another NNMVS)           
  151.  in a different PIE MultiTSO session.  It prevents your users from              
  152.  crashing TCP/IP, so it is highly recommended that you make use of it.          
  153.                                                                                 
  154.  4. Customize the NNMMAIL exec to invoke your local mailer, or                  
  155.  otherwise insure that messages sent via MAIL or REPLY arrive at their          
  156.  intended destination.                                                          
  157.                                                                                 
  158.  5. If you are running ISPF Version 2 or earlier, edit the NNMVS panels         
  159.  whose names begin "NNMP...".  These are popups, and will not work              
  160.  under ISPF Version 2 unless you change the )BODY line.  Remove the             
  161.  WINDOW(...) parameter from the )BODY line of each panel so that the            
  162.  line just says )BODY or )BODY EXPAND(``), as the case may be.                  
  163.                                                                                 
  164.  Note:  You may wish to customize the TNNMSERV tutorial panel to                
  165.  include the names of all available NNTP servers at your site.                  
  166.                                                                                 
  167.  Now, to install:                                                               
  168.                                                                                 
  169.  6. Submit the ALLOAD JCL to allocate the load library from which the           
  170.  executable program will be run.  If you intend to place the executable         
  171.  into an existing library, you can skip this step, but you should make          
  172.  sure that there is no previous load module named NNMMAIN in the load           
  173.  library of your choice before you proceed.                                     
  174.                                                                                 
  175.  7. Submit the COMPILE JCL to compile all the C sources and create the          
  176.  executable NNMVS load module.                                                  
  177.                                                                                 
  178.  The first time you run this you can expect a return code of 8 from             
  179.  the linkedit.  Like SMP/E, this is OK if the only reason is an IEW0342         
  180.  because the "INCLUDE SYSLMOD(NNMMAIN)" did not find an existing load           
  181.  module.  If you get IEW0132 (unresolved external reference) or                 
  182.  IEW0241 (ESD type definition conflict), your linkedit went awry.               
  183.  Don't use the resultant load module.  Check the libraries you                  
  184.  specified on the link step to see what went wrong.                             
  185.                                                                                 
  186.  In the future, if you have to recompile individual modules, you can use        
  187.  the same JCL to compile only those modules, and the link will include          
  188.  the new modules in the existing executable load module.                        
  189.                                                                                 
  190.  Note:  If you have defined C370V1 in the NNUSER header file, you must          
  191.  also include the system linklist load library or libraries containing          
  192.  ISPLINK, ISPEXEC and IKJEFF18 when linking.  Otherwise you may delete          
  193.  the lines from the linkedit JCL that reference them.                           
  194.                                                                                 
  195.  Note:  You need not include the PASCAL libraries or the AMPZMVSB               
  196.  module if you are using TCP/IP Version 2 or higher, in which case              
  197.  you must also define TCPIPV2 in the NNUSER headerfile.                         
  198.                                                                                 
  199.  8. Copy the HELP member of the CNTL library into the data set which            
  200.  will be allocated to ddname NNBATHLP by the NNMVS batch mode JCL               
  201.  procedure.  This data set contains the text printed by the batch HELP          
  202.  command.  The distributed proc calls this 'NNMVS.HELP' - change it to          
  203.  match the name of your data set (sequential, or member of a PDS).              
  204.                                                                                 
  205.  9. Copy the NNMVS (or NNMVSC or NNMVSP) and NNMMAIL execs into your            
  206.  installation CLIST or REXX library.  Also copy the NNMVSL exec if              
  207.  you want access to Leonard Woren's experimental multiple-server dialog.        
  208.                                                                                 
  209.  10. If you use the NNMVSP version of the exec, copy the NNMVSHLP               
  210.  member of the CNTL PDS into your installation TSO HELP library                 
  211.  under the same name as you gave the exec, so folks can type HELP xxx           
  212.  where xxx is the name of the exec.  If you have local help that you            
  213.  want to include (like names of local servers, posting guidelines,              
  214.  or whatever), create a HELP member called NNMVSLOC and install it              
  215.  in the same library.                                                           
  216.                                                                                 
  217.  11. Copy all the members of the panel PDS into the ISPF panel library          
  218.  specified in the NNMVS exec.                                                   
  219.                                                                                 
  220. --------------------------------------------------------------------            
  221.                                                                                 
  222.  Note:  Make sure that the C/370 run time library is available,                 
  223.  either in the system link list or in the ISPLLIB concatenation,                
  224.  before attempting to run NNMVS.                                                
  225.                                                                                 
  226.  If the C/370 runtime library is not in the link list or otherwise              
  227.  available to ISPF at execution time, you may arrange for it to be              
  228.  allocated via LIBDEF in the NNMVS exec (I haven't tried this).                 
  229.                                                                                 
  230. --------------------------------------------------------------------            
  231.                                                                                 
  232.  Questions?  Comments?  Suggestions?  Gripes?  Requests?  Musings?              
  233.                                                                                 
  234.  You can communicate all of these via the LISTSERV mailing list                 
  235.  NNMVS-L, maintained at VM.USC.EDU.  To get on this list, send mail to          
  236.  LISTSERV@USCVM (or LISTSERV@VM.USC.EDU) with the following line in             
  237.  the message body:                                                              
  238.                                                                                 
  239.    SUBSCRIBE NNMVS-L firstname lastname                                         
  240.                                                                                 
  241.  Please keep in mind that further requests (e.g. to unsubscribe from            
  242.  the list) must be sent to the LISTSERV address, *not* to the list.             
  243.  The response you'll get from the SUBSCRIBE message will tell you               
  244.  about this and more - so be sure to save it.                                   
  245.                                                                                 
  246. --------------------------------------------------------------------            
  247.                                                                                 
  248.  Please email all other correspondence to...                                    
  249.                                                                                 
  250.  Steve Bacher      <seb@draper.com> or <seb1525@mvs.draper.com>                 
  251.                                                                                 
  252. ./   ADD NAME=$CHANGES,SSI=01040025                                             
  253.                                                                                 
  254.  Latest Fixes to This Release                                                   
  255.                                                                                 
  256.  NNMCLRNG.C: - Fix memory leak when exiting from NNMVS.                         
  257.                                                                                 
  258.  NNMDLANG.C: - Fix 0C4 in "new newsgroups" function when the server             
  259.                has duplicate entries in the active.times file.                  
  260.                                                                                 
  261.              - Check for bad output from news server's active file              
  262.                in the NNTP LIST command, adjust counts and display a            
  263.                nasty message so the user can nag the administrator.             
  264.                                                                                 
  265.  NNMBPEXT.C: - Fix bug whereby all article headers were being                   
  266.                retrieved even when EXTRACT UNREAD was requested                 
  267.                in a batch job, causing excessive resource usage                 
  268.                and memory blowouts.                                             
  269.                                                                                 
  270.  New Features In V2 R4                                                          
  271.                                                                                 
  272.  * Memory usage has been improved significantly.                                
  273.                                                                                 
  274.  * Handling of missing/expired articles has been improved.                      
  275.                                                                                 
  276.  * Miscellaneous Bug Fixes                                                      
  277.                                                                                 
  278.  * Enhancements to NNMVSP Exec                                                  
  279.                                                                                 
  280.  New Features In V2 R3 M2                                                       
  281.                                                                                 
  282.  * New commands:                                                                
  283.                                                                                 
  284.  - SORT Subject / Number - in article viewing mode, you may use this            
  285.    command to sort the article display by subject or return it to the           
  286.    default article-number order.  Note that this may require a lot of           
  287.    processing, both to retrieve article titles and to perform the               
  288.    sorting, which tries to match messages up with "re:" replies.                
  289.    When the LOCATE command is issued from an article display in this            
  290.    mode, it takes a character string rather than a number.                      
  291.                                                                                 
  292.  - QUIT - from almost any panel, terminates NNMVS immediately.                  
  293.    It works like repeated END's, which means that it will save                  
  294.    your NEWSRC file.  (QUIT from display-new-newsgroups or                      
  295.    display-bogus-newsgroups skips updating NEWSRC, though, for                  
  296.    your protection.)                                                            
  297.                                                                                 
  298.  * Miscellaneous changes:                                                       
  299.                                                                                 
  300.    The MARKALL and UNMARKALL commands now prompt you as to whether              
  301.    you want to mark all the articles in the newsgroup or just the               
  302.    ones currently shown in the table.                                           
  303.                                                                                 
  304.  * The extra blank line that used to appear at the bottom of articles           
  305.    is gone.  There may be some effects on article extraction,                   
  306.    particularly when append mode is used, but in general this means             
  307.    that what you get is more like what is really out there.                     
  308.                                                                                 
  309.  * In POST and MAIL, the format of the inserted message and the                 
  310.    dashed line separating the signature from the body have been                 
  311.    changed to be more in accordance with standard practice.                     
  312.                                                                                 
  313.  * Even more tweaking of missing article handling.  It's better                 
  314.    than it was, and may even be considered acceptable now.                      
  315.                                                                                 
  316.  * Removed Features                                                             
  317.                                                                                 
  318.    Apologies:  The PATH variable in batch has been removed.                     
  319.    It was of dubious value (I'm sure you don't miss it).                        
  320.    Basically, we needed the slot to implement subject sorting.                  
  321.                                                                                 
  322.  New Features In V2 R3 M1                                                       
  323.                                                                                 
  324.  * A user option to turn automatic scrolling on or off in the                   
  325.    newsgroup and article display tables has been added.                         
  326.                                                                                 
  327.  * In POST and MAIL, headers are no longer inserted into the text of            
  328.    your reply.  Instead, a message of the form                                  
  329.     "In article <messageid> on <date>, <author> writes:"                        
  330.    is inserted.                                                                 
  331.                                                                                 
  332.  * Remaining bugs and pitfalls of missing articles are finally                  
  333.    cleared up (hopefully).                                                      
  334.                                                                                 
  335.  * The ONLY and FIND commands in article display mode will cause                
  336.    fetching of article headers if you are in "A" (all articles) mode.           
  337.                                                                                 
  338.  * An OPTION operand has been added to the NNMVS exec, and support has          
  339.    been added to NNMVS so that you will go directly to the requested            
  340.    option if you use this and provide a number of other values.                 
  341.                                                                                 
  342.  * An attempt to protect users from crashing TCP/IP with multiple               
  343.    copies of socket applications is included.                                   
  344.                                                                                 
  345.  New Features In V2 R3                                                          
  346.                                                                                 
  347.  * New Commands for Controlling Newsgroup and Article Displays                  
  348.                                                                                 
  349.    Note: In the following descriptions of operands, "strings" are               
  350.    unquoted single words or strings quoted with either single or double         
  351.    quotes.  Case is ignored.                                                    
  352.                                                                                 
  353.    The following new commands are available on the newsgroup display:           
  354.                                                                                 
  355.      ORDER {Alphabetic/List} - specify the order in which the groups are        
  356.      listed.  The initial setting is A (alphabetic).  You may change to         
  357.      L (list) to view the newsgroups in the same order as the NNTP              
  358.      server's active file (what the NNTP "LIST" command returns).               
  359.                                                                                 
  360.      ONLY "string" - limit the newsgroup display to newsgroups with             
  361.      "string" in the name.  Type ONLY with no operands to restore               
  362.      the display to all newsgroups (or registered, depending).                  
  363.                                                                                 
  364.      FIND "string" {NEXT/PREV/FIRST/LAST} - position the newsgroup              
  365.      display to the next, previous, first or last group which has               
  366.      "string" in the name.  FIND with no operands repeats the find.             
  367.                                                                                 
  368.    The following new commands are available on the article display:             
  369.                                                                                 
  370.      ONLY "string" - limit the article display to articles with                 
  371.      "string" in the subject.  Type ONLY with no operands to restore            
  372.      the display to all articles (read or unread, depending).                   
  373.                                                                                 
  374.      FIND "string" {NEXT/PREV/FIRST/LAST} - position the article                
  375.      display to the next, previous, first or last article which has             
  376.      "string" in the subject.  FIND with no operands repeats the find.          
  377.                                                                                 
  378.  * New Options for Navigating Article Views                                     
  379.                                                                                 
  380.    The following new commands are available from article browse:                
  381.                                                                                 
  382.      NEXTU or NU - like NEXT but goes to the next unread article.               
  383.                                                                                 
  384.      NEXTT or NT - like NEXT but goes to the next article currently in          
  385.                    the table.  When you use ONLY to filter the article          
  386.                    display, NEXTT honors the filter.  NEXT doesn't.             
  387.                                                                                 
  388.      NEXTS or NS - like NEXT but goes to the next article in the current        
  389.                    subject thread.                                              
  390.                                                                                 
  391.      PREVU(PU), PREVT(PT), PREVS(PS) are analogous to the above.                
  392.                                                                                 
  393.      FIRSTSUBJ or FS - goes to the first article in the current                 
  394.                        subject thread.                                          
  395.      LASTSUBJ or LS  - goes to the last article in the current                  
  396.                        subject thread.                                          
  397.      NEWSUBJ or NS   - goes to the first unread article of a subject            
  398.                        other than the current thread.                           
  399.      SUBJECT or SUBJ - displays or changes the current subject.                 
  400.                                                                                 
  401.  * Prompting to Protect Existing Data Sets on EXTRACT                           
  402.                                                                                 
  403.    When you use the EXTRACT command, if the data set already exists             
  404.    you will get a pop-up asking you to confirm that you want to                 
  405.    reuse the data set.  Simply press ENTER to do so.                            
  406.                                                                                 
  407.  * Changes To Commands                                                          
  408.                                                                                 
  409.    The NNTP command may now be specified like this:                             
  410.                                                                                 
  411.      NNTP   - by itself, puts you in the NNTP panel, as before                  
  412.      NNTP nntp-command   - executes NNTP command immediately                    
  413.                                                                                 
  414.      For example:  NNTP GROUP COMP.LANG.LISP                                    
  415.                    NNTP HELP                                                    
  416.                                                                                 
  417.    The OPTIONS command has been changed to take you to a menu of                
  418.    general options.  The RFC822 header settings are now option 1.               
  419.    You can type OPT 1 to go directly there if you don't want to                 
  420.    see the extra panel.  Also, in BROWSE, you can type HEADERS                  
  421.    (or HEADER) instead of OPTION to go directly to the RFC822                   
  422.    header setting panel.                                                        
  423.                                                                                 
  424.    In addition to RFC822 header display options, you may now specify            
  425.    how you want screen displays to tell you about operations in process.        
  426.    (There are some fancy new ways that NNMVS can do this.)                      
  427.    You can also control the prompting for overwriting on EXTRACT.               
  428.                                                                                 
  429.  * Changes to Selection Codes                                                   
  430.                                                                                 
  431.    When you select "A" to see all the articles in a newsgroup,                  
  432.    NNMVS will fill in the title lines.  No more empty lines.                    
  433.    To save processing, it will get only those that are necessary                
  434.    to fill your screen.  Scrolling down (or up) will get the next               
  435.    batch - this will appear to be slower.                                       
  436.                                                                                 
  437.    Also, only those articles that have actually been fetched (not               
  438.    just the headers) will be retained in the table when you switch              
  439.    back to using "S" to look at the articles in the newsgroup.                  
  440.                                                                                 
  441.    Note that whether you select "A" or "S" will affect subject                  
  442.    searches.  If you selected "S", subject searches will be limited             
  443.    to unread or already-retrieved articles.  If you selected "A",               
  444.    subject searches will retrieve previously read articles, and                 
  445.    potentially take longer.                                                     
  446.                                                                                 
  447.    You can select "N" to view only new (unseen) articles.  "N" is               
  448.    like "S" except that articles are removed from the display once              
  449.    they are read whenever you reenter the article display or change             
  450.    the viewing criteria.                                                        
  451.                                                                                 
  452.    The "Z" option, which will remain undocumented for now, is similar           
  453.    to the "A" option except that it retrieves NO articles headers,              
  454.    read or unread.  Good for quick entry into a huge newsgroup, but             
  455.    not very good at recording the correct status of the articles.               
  456.                                                                                 
  457.    You can select "C" to cancel an article by posting a control request         
  458.    to the server.  You must be the original author (poster) of the              
  459.    article to be allowed to cancel it.  Cancellation is implemented             
  460.    by sending a control message to the NNTP server.                             
  461.                                                                                 
  462.  * POST, FOLLOWUP and REPLY now allow you to specify a Reply-to email           
  463.    address and a signature file.  In addition, you may specify a                
  464.    Followup-to list of newsgroups on POST or FOLLOWUP.                          
  465.                                                                                 
  466.  * FOLLOWUP and REPLY now follow the RFC1036 rules for generating               
  467.    the default lists of newsgroups to post to and mail address to               
  468.    reply to.  FOLLOWUP even checks if the Followup-to: header says              
  469.    "poster" or contains an email address, and strongly suggests                 
  470.    that you email instead of posting.  Since BITNET postings dont               
  471.    conform to RFC standards, the actual From: address is displayed              
  472.    for REPLY in case you need to type it in.                                    
  473.                                                                                 
  474.  * New Batch mode variable CHECKPOINT allows you to control whether the         
  475.    NEWSRC file gets rewritten on every change or just at the end of a           
  476.    batch run.  Good for preventing NEWSRC wipeouts on 322 abends.               
  477.                                                                                 
  478.  * Support for Multiple NNMVS's in a Single TSO Session                         
  479.    (assuming that they're talking to two different servers and                  
  480.    that you have the required TCP/IP multitasking socket support                
  481.    APAR from IBM).                                                              
  482.                                                                                 
  483.    Basically, it dynamically generates a ddname for the newsrc file,            
  484.    and you can specify different newsrc files, so there you go.                 
  485.                                                                                 
  486.    Warning:  PIE users - DO NOT run 2 NNMVS's from different PIE                
  487.    sessions - the IBM TCP/IP fix doesn't work for this!  Use ISPF               
  488.    split screen to do it.                                                       
  489.                                                                                 
  490.  * Optional Driver CLIST and REXX exec using XPROC to specify                   
  491.    parameters in CLIST-style Syntax                                             
  492.                                                                                 
  493.    See installation instructions for details.                                   
  494.                                                                                 
  495. ./   ADD NAME=$MISC,SSI=01030003                                                
  496.                                                                                 
  497. Miscellaneous Notes and Gotchas                                                 
  498.                                                                                 
  499. ========================================================================        
  500.                                                                                 
  501.  * C/370 Kanji Feature                                                          
  502.                                                                                 
  503.  If your C/370 was not installed properly (e.g. you assumed that CBIPO          
  504.  would take care of everything - you wretched fool!), it is possible            
  505.  that you have the wrong national language for messages.  This will             
  506.  become apparent as soon as you fail to open a file, since the C/370            
  507.  perror() function will write gibberish to stderr.  To fix this, bug            
  508.  your MVS systems programmer to reinstall C/370, e.g. with JDL1214              
  509.  and without JCLB212 (for V2R1).  It may be more complicated than that.         
  510.                                                                                 
  511. ========================================================================        
  512.                                                                                 
  513.  * C/370 Attention Handling                                                     
  514.                                                                                 
  515. C/370 doesn't handle PA1 (attention) interrupts properly - in fact,             
  516. it completely screws them up, so you end up in an unbreakable loop              
  517. when you try to break out of a C/370 application running under ISPF             
  518. that uses the TCP/IP socket library.                                            
  519.                                                                                 
  520. As a temporary circumvention, you should apply a zap to module IBMBLIIA         
  521. in your run-time load library.  The zap for C/370 V2R1, for example,            
  522. looks like this:                                                                
  523.                                                                                 
  524.    NAME IBMBLIIA IBMBLII1                                                       
  525.    VER 2250 0A60                                                                
  526.    REP 2250 1BFF                                                                
  527.                                                                                 
  528.   I.E., find the SVC 96 (STAX) instruction and NOP it.                          
  529.                                                                                 
  530.   Go ahead and apply it (preferably to a copy of IBMBLIIA in a user             
  531.   library from which you run your favorite C/370 application, like              
  532.   NNMVS, for example).  Now you can feel free to do anything you like,          
  533.   because you can always attention out.                                         
  534.                                                                                 
  535.   If you find that you need this zap, please make sure that IBM hears           
  536.   from you about the problem.   The more customers they hear from, the          
  537.   more likely it is that something will be done to fix it.                      
  538.                                                                                 
  539.   Be aware that this turns off attention handling entirely - but this           
  540.   has turned out to be the only desirable behavior.  Note that SIGINT           
  541.   handling has never worked in C/370.  If you don't believe this, then          
  542.   just compile and run the sample program in member SIGFAIL.                    
  543.                                                                                 
  544. ./   ADD NAME=ALLOAD,SSI=01040000                                               
  545. //JOBNAME  JOB ACCOUNT,'NAME'                                                   
  546. //*                                                                  */         
  547. //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  548. //*                                                                  */         
  549. //* This software is provided on an "AS IS" basis.  All warranties,  */         
  550. //* including the implied warranties of merchantability and fitness, */         
  551. //* are expressly denied.                                            */         
  552. //*                                                                  */         
  553. //* Provided this copyright notice is included, this software may    */         
  554. //* be freely distributed and not offered for sale.                  */         
  555. //*                                                                  */         
  556. //* Changes or modifications may be made and used only by the maker  */         
  557. //* of same, and not further distributed.  Such modifications should */         
  558. //* be mailed to the author for consideration for addition to the    */         
  559. //* software and incorporation in subsequent releases.               */         
  560. //*                                                                  */         
  561. //*                                                                             
  562. //* Allocate NNMVS load library before install                                  
  563. //*                                                                             
  564. //NNALLOC PROC BS='6233',U='3380',V='',                                         
  565. //             PRI='100',SEC='100',DIR='35'                                     
  566. //*                                                                             
  567. //IEFBR14  EXEC PGM=IEFBR14                                                     
  568. //ALLOCDD  DD   DISP=(NEW,CATLG,DELETE),DSN=&LIB,                               
  569. //         DCB=(RECFM=U,BLKSIZE=&BS),                                           
  570. //         SPACE=(&BS,(&PRI,&SEC,&DIR)),UNIT=&U,VOL=SER=&V                      
  571. //*                                                                             
  572. //         PEND                                                                 
  573. //*                                                                             
  574. //* The following step allocates the load library from which the                
  575. //* executable program will be run.  If you intend to place the                 
  576. //* executable into an existing library, you can skip this step.                
  577. //* Otherwise, the name must match the name used on the LOADLIB                 
  578. //* parameter of the NNLINK procedure in the COMPILE JCL.                       
  579. //*                                                                             
  580. //ALLOC1   EXEC NNALLOC,PRI=50,SEC=50,DIR=35,                                   
  581. //         LIB='NNMVS.LOAD'                                                     
  582. //*                                                                             
  583. ./   ADD NAME=AUTH,SSI=01000039                                                 
  584. #                                                                               
  585. # This file is used by NNTP clients (NNMVS) on this system to connect           
  586. # to news servers that require authentication, according to the new             
  587. # NNTO authorization protocol.  It is ignored if the news server does           
  588. # not support this protocol.  If the news server supports it, the user          
  589. # must be defined in the server host's /etc/passwd file and its uid             
  590. # must be the same as the uid of the user "nntp" - otherwise the server         
  591. # will disconnect the client.                                                   
  592. #                                                                               
  593. # A server given here without a user or password will be accepted               
  594. # by NNMVS without an attempt to gain the server's authorization.               
  595. #                                                                               
  596. # serverhost  user  password                                                    
  597. #                                                                               
  598.   AUTHHOST    NNTP  JOSHUA                                                      
  599.   NOAUTHHOST                                                                    
  600. ./   ADD NAME=COMPILE                                                           
  601. //JOBNAME  JOB ACCOUNT,'NAME'                                                   
  602. //*                                                                  */         
  603. //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  604. //*                                                                  */         
  605. //* This software is provided on an "AS IS" basis.  All warranties,  */         
  606. //* including the implied warranties of merchantability and fitness, */         
  607. //* are expressly denied.                                            */         
  608. //*                                                                  */         
  609. //* Provided this copyright notice is included, this software may    */         
  610. //* be freely distributed and not offered for sale.                  */         
  611. //*                                                                  */         
  612. //* Changes or modifications may be made and used only by the maker  */         
  613. //* of same, and not further distributed.  Such modifications should */         
  614. //* be mailed to the author for consideration for addition to the    */         
  615. //* software and incorporation in subsequent releases.               */         
  616. //*                                                                  */         
  617. //*********************************************************************         
  618. //*                                                                             
  619. //* Compile some or all NNMVS C/370 sources to make the SYSLIN input            
  620. //* to the linkedit of the executable NNMMAIN load module.                      
  621. //*                                                                             
  622. //NNCCL  PROC MEMBER=,                                                          
  623. //            SRCLIB='NNMVS.C',                  NNMVS C source PDS             
  624. //            HDRLIB='NNMVS.H',                  NNMVS C headers PDS            
  625. //            COMMHDR='TCPIP.COMMMAC',           C/370 TCP/IP headers           
  626. //            C370HDR='SYS1.EDCHDRS',            C/370 standard headers         
  627. //            SYSMSGS='SYS1.EDCMSGS',            C/370 messages file            
  628. //            SYSMSGM='EDCMSGE',                 C/370 message member           
  629. //            VIOUNIT=VIO,                       Temporary disk unit            
  630. //            OUTCLAS='*',                          SYSOUT class                
  631. //            CPARMS='SOURCE EXPMAC NOAGGR NOXREF', Compile parameters          
  632. //            TEST=TEST                             TEST or NOTEST              
  633. //*                                                                             
  634. //CCOMP     EXEC PGM=EDCCOMP,PARM='MARGINS(1,72) &TEST &CPARMS'                 
  635. //SYSMSGS   DD DISP=SHR,DSN=&SYSMSGS(&SYSMSGM)                                  
  636. //SYSIN     DD DISP=SHR,DSN=&SRCLIB(&MEMBER)                                    
  637. //SYSLIB    DD DISP=SHR,DSN=&COMMHDR                                            
  638. //          DD DISP=SHR,DSN=&C370HDR                                            
  639. //USERLIB   DD DISP=SHR,DSN=&HDRLIB                                             
  640. //SYSLIN    DD DSN=&&LOADSET,UNIT=&VIOUNIT,DISP=(MOD,PASS),                     
  641. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  642. //SYSPRINT  DD SYSOUT=&OUTCLAS                                                  
  643. //SYSCPRT   DD SYSOUT=&OUTCLAS                                                  
  644. //SYSUT1    DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  645. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  646. //SYSUT4    DD DSN=&&SYSUT4,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  647. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)                 
  648. //SYSUT6    DD DSN=&&SYSUT6,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  649. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  650. //SYSUT7    DD DSN=&&SYSUT7,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  651. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  652. //SYSUT8    DD DSN=&&SYSUT8,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  653. //   SPACE=(32000,(30,30)),DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)              
  654. //SYSUT9    DD DSN=&&SYSUT9,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  655. //   SPACE=(32000,(30,30)),DCB=(RECFM=VB,LRECL=137,BLKSIZE=882)                 
  656. //SYSUT10   DD SYSOUT=&OUTCLAS                                                  
  657. //*                                                                             
  658. //         PEND                                                                 
  659. //*                                                                             
  660. //*********************************************************************         
  661. //*                                                                             
  662. //* Linkedit the executable NNMMAIN load module.                                
  663. //*                                                                             
  664. //* Note: If C/370 V1R2 or higher, and you have therefore accepted              
  665. //*       the "#define FETCH" in the NN header, you may delete                  
  666. //*       the line that includes the ISPLINK library.                           
  667. //*                                                                             
  668. //* Note: If TCP/IP V2 or higher, remove the PASCAL link libraries              
  669. //*       from the JCL and the AMPZMVSB card from the control deck.             
  670. //*                                                                             
  671. //NNLINK PROC LOADLIB='NNMVS.LOAD',              Executable load library        
  672. //            PLIBASE='SYS1.PLIBASE',            PL/1   link library            
  673. //            EDCBASE='SYS1.SEDCBASE',           C/370  link library            
  674. //            IBMBASE='SYS1.SIBMBASE',           PL/1+C common library          
  675. //            COMMTXT='TCPIP.COMMTXT',           TCP/IP link library            
  676. //            PASRUN3='SYS1.PAS.SAMPRUN3',       PASCAL link library            
  677. //            PASRUN1='SYS1.PAS.SAMPRUN1',       PASCAL link library            
  678. //            PASMSG1='SYS1.PAS.SAMPMSG1',       PASCAL link library            
  679. //            ISPLINK='ISP.V3R2M0.ISPLLIB',      ISPLINK link library           
  680. //            VIOUNIT=VIO,                       Temporary disk unit            
  681. //            OUTCLAS='*',                          SYSOUT class                
  682. //            LPARMS='LIST,LET,MAP',                Linkedit parameters         
  683. //            TEST=TEST                             TEST or NOTEST              
  684. //*                                                                             
  685. //LKED      EXEC PGM=IEWL,PARM='AMODE(31),&TEST,&LPARMS'                        
  686. //SYSPRINT  DD SYSOUT=&OUTCLAS                                                  
  687. //SYSLIB    DD DISP=SHR,DSN=&PLIBASE                                            
  688. //          DD DISP=SHR,DSN=&EDCBASE                                            
  689. //          DD DISP=SHR,DSN=&IBMBASE                                            
  690. //          DD DISP=SHR,DSN=&COMMTXT                                            
  691. //          DD DISP=SHR,DSN=&PASRUN3  if TCP/IP V1 only                         
  692. //          DD DISP=SHR,DSN=&PASRUN1  if TCP/IP V1 only                         
  693. //          DD DISP=SHR,DSN=&PASMSG1  if TCP/IP V1 only                         
  694. //          DD DISP=SHR,DSN=&ISPLINK  if C/370 V1R1 with #undef FETCH           
  695. //SYSLMOD   DD DISP=SHR,DSN=&LOADLIB                                            
  696. //SYSUT1    DD DSN=&&SYSUT1,UNIT=&VIOUNIT,DISP=(NEW,DELETE),                    
  697. //          SPACE=(32000,(30,30))                                               
  698. //*                                                                             
  699. //         PEND                                                                 
  700. //*                                                                             
  701. //NNMADDNG EXEC NNCCL,MEMBER=NNMADDNG                                           
  702. //NNMADJUA EXEC NNCCL,MEMBER=NNMADJUA                                           
  703. //NNMALLAV EXEC NNCCL,MEMBER=NNMALLAV                                           
  704. //NNMALLOC EXEC NNCCL,MEMBER=NNMALLOC                                           
  705. //NNMAUTH  EXEC NNCCL,MEMBER=NNMAUTH                                            
  706. //NNMBATCH EXEC NNCCL,MEMBER=NNMBATCH                                           
  707. //NNMBBEXP EXEC NNCCL,MEMBER=NNMBBEXP                                           
  708. //NNMBCONN EXEC NNCCL,MEMBER=NNMBCONN                                           
  709. //NNMBDECL EXEC NNCCL,MEMBER=NNMBDECL                                           
  710. //NNMBFLUS EXEC NNCCL,MEMBER=NNMBFLUS                                           
  711. //NNMBGCMD EXEC NNCCL,MEMBER=NNMBGCMD                                           
  712. //NNMBGDO  EXEC NNCCL,MEMBER=NNMBGDO                                            
  713. //NNMBGEXP EXEC NNCCL,MEMBER=NNMBGEXP                                           
  714. //NNMBGTOK EXEC NNCCL,MEMBER=NNMBGTOK                                           
  715. //NNMBPDEC EXEC NNCCL,MEMBER=NNMBPDEC                                           
  716. //NNMBPDER EXEC NNCCL,MEMBER=NNMBPDER                                           
  717. //NNMBPELS EXEC NNCCL,MEMBER=NNMBPELS                                           
  718. //NNMBPEXE EXEC NNCCL,MEMBER=NNMBPEXE                                           
  719. //NNMBPEXT EXEC NNCCL,MEMBER=NNMBPEXT                                           
  720. //NNMBPFOR EXEC NNCCL,MEMBER=NNMBPFOR                                           
  721. //NNMBPHEL EXEC NNCCL,MEMBER=NNMBPHEL                                           
  722. //NNMBPIF  EXEC NNCCL,MEMBER=NNMBPIF                                            
  723. //NNMBPLIS EXEC NNCCL,MEMBER=NNMBPLIS                                           
  724. //NNMBPMAR EXEC NNCCL,MEMBER=NNMBPMAR                                           
  725. //NNMBPNNT EXEC NNCCL,MEMBER=NNMBPNNT                                           
  726. //NNMBPPUT EXEC NNCCL,MEMBER=NNMBPPUT                                           
  727. //NNMBPQUE EXEC NNCCL,MEMBER=NNMBPQUE                                           
  728. //NNMBPQUI EXEC NNCCL,MEMBER=NNMBPQUI                                           
  729. //NNMBPREG EXEC NNCCL,MEMBER=NNMBPREG                                           
  730. //NNMBPSET EXEC NNCCL,MEMBER=NNMBPSET                                           
  731. //NNMBPVAR EXEC NNCCL,MEMBER=NNMBPVAR                                           
  732. //NNMBRIFC EXEC NNCCL,MEMBER=NNMBRIFC                                           
  733. //NNMBRIFR EXEC NNCCL,MEMBER=NNMBRIFR                                           
  734. //NNMBSOUT EXEC NNCCL,MEMBER=NNMBSOUT                                           
  735. //NNMBSYNT EXEC NNCCL,MEMBER=NNMBSYNT                                           
  736. //NNMBTEXT EXEC NNCCL,MEMBER=NNMBTEXT                                           
  737. //NNMBTRAS EXEC NNCCL,MEMBER=NNMBTRAS                                           
  738. //NNMBVGET EXEC NNCCL,MEMBER=NNMBVGET                                           
  739. //NNMBVPUT EXEC NNCCL,MEMBER=NNMBVPUT                                           
  740. //NNMBXFAR EXEC NNCCL,MEMBER=NNMBXFAR                                           
  741. //NNMBXFNG EXEC NNCCL,MEMBER=NNMBXFNG                                           
  742. //NNMCLRNG EXEC NNCCL,MEMBER=NNMCLRNG                                           
  743. //NNMCLRTX EXEC NNCCL,MEMBER=NNMCLRTX                                           
  744. //NNMCNRF  EXEC NNCCL,MEMBER=NNMCNRF                                            
  745. //NNMCONN  EXEC NNCCL,MEMBER=NNMCONN                                            
  746. //NNMCOPY  EXEC NNCCL,MEMBER=NNMCOPY                                            
  747. //NNMDCAN  EXEC NNCCL,MEMBER=NNMDCAN                                            
  748. //NNMDFAIL EXEC NNCCL,MEMBER=NNMDFAIL                                           
  749. //NNMDISC  EXEC NNCCL,MEMBER=NNMDISC                                            
  750. //NNMDISPL EXEC NNCCL,MEMBER=NNMDISPL                                           
  751. //NNMDLANG EXEC NNCCL,MEMBER=NNMDLANG                                           
  752. //NNMDMAIL EXEC NNCCL,MEMBER=NNMDMAIL                                           
  753. //NNMDMENU EXEC NNCCL,MEMBER=NNMDMENU                                           
  754. //NNMDNG   EXEC NNCCL,MEMBER=NNMDNG                                             
  755. //NNMDNNTP EXEC NNCCL,MEMBER=NNMDNNTP                                           
  756. //NNMDOIT  EXEC NNCCL,MEMBER=NNMDOIT                                            
  757. //NNMDPOST EXEC NNCCL,MEMBER=NNMDPOST                                           
  758. //NNMDSOPT EXEC NNCCL,MEMBER=NNMDSOPT                                           
  759. //NNMDUMP  EXEC NNCCL,MEMBER=NNMDUMP                                            
  760. //NNMESRVR EXEC NNCCL,MEMBER=NNMESRVR                                           
  761. //NNMESTNG EXEC NNCCL,MEMBER=NNMESTNG                                           
  762. //NNMFREEM EXEC NNCCL,MEMBER=NNMFREEM                                           
  763. //NNMGETDS EXEC NNCCL,MEMBER=NNMGETDS                                           
  764. //NNMGETM  EXEC NNCCL,MEMBER=NNMGETM                                            
  765. //NNMGSRVL EXEC NNCCL,MEMBER=NNMGSRVL                                           
  766. //NNMIERR  EXEC NNCCL,MEMBER=NNMIERR                                            
  767. //NNMIGET  EXEC NNCCL,MEMBER=NNMIGET                                            
  768. //NNMINIT  EXEC NNCCL,MEMBER=NNMINIT                                            
  769. //NNMISPF  EXEC NNCCL,MEMBER=NNMISPF                                            
  770. //NNMIVGET EXEC NNCCL,MEMBER=NNMIVGET                                           
  771. //NNMIVPUT EXEC NNCCL,MEMBER=NNMIVPUT                                           
  772. //NNMMAIN  EXEC NNCCL,MEMBER=NNMMAIN                                            
  773. //NNMMARR  EXEC NNCCL,MEMBER=NNMMARR                                            
  774. //NNMMARU  EXEC NNCCL,MEMBER=NNMMARU                                            
  775. //NNMNNTP  EXEC NNCCL,MEMBER=NNMNNTP                                            
  776. //NNMONRF  EXEC NNCCL,MEMBER=NNMONRF                                            
  777. //NNMOUTTX EXEC NNCCL,MEMBER=NNMOUTTX                                           
  778. //NNMPICK  EXEC NNCCL,MEMBER=NNMPICK                                            
  779. //NNMPMSG  EXEC NNCCL,MEMBER=NNMPMSG                                            
  780. //NNMPNG   EXEC NNCCL,MEMBER=NNMPNG                                             
  781. //NNMPNRL  EXEC NNCCL,MEMBER=NNMPNRL                                            
  782. //NNMPTX   EXEC NNCCL,MEMBER=NNMPTX                                             
  783. //NNMQAR   EXEC NNCCL,MEMBER=NNMQAR                                             
  784. //NNMQNG   EXEC NNCCL,MEMBER=NNMQNG                                             
  785. //NNMRAARH EXEC NNCCL,MEMBER=NNMRAARH                                           
  786. //NNMRARH  EXEC NNCCL,MEMBER=NNMRARH                                            
  787. //NNMRBFM  EXEC NNCCL,MEMBER=NNMRBFM                                            
  788. //NNMRECON EXEC NNCCL,MEMBER=NNMRECON                                           
  789. //NNMRPERR EXEC NNCCL,MEMBER=NNMRPERR                                           
  790. //NNMSAVE  EXEC NNCCL,MEMBER=NNMSAVE                                            
  791. //NNMSOCKT EXEC NNCCL,MEMBER=NNMSOCKT                                           
  792. //NNMSOPT  EXEC NNCCL,MEMBER=NNMSOPT                                            
  793. //NNMSORT  EXEC NNCCL,MEMBER=NNMSORT                                            
  794. //NNMSSRVR EXEC NNCCL,MEMBER=NNMSSRVR                                           
  795. //NNMSTRLC EXEC NNCCL,MEMBER=NNMSTRLC                                           
  796. //NNMSUMAT EXEC NNCCL,MEMBER=NNMSUMAT                                           
  797. //NNMTSO   EXEC NNCCL,MEMBER=NNMTSO                                             
  798. //NNMUNALC EXEC NNCCL,MEMBER=NNMUNALC                                           
  799. //NNMUPDT  EXEC NNCCL,MEMBER=NNMUPDT                                            
  800. //NNMVAR   EXEC NNCCL,MEMBER=NNMVAR                                             
  801. //NNMVNG   EXEC NNCCL,MEMBER=NNMVNG                                             
  802. //NNMVTX   EXEC NNCCL,MEMBER=NNMVTX                                             
  803. //NNMXARTT EXEC NNCCL,MEMBER=NNMXARTT                                           
  804. //NNMXARTX EXEC NNCCL,MEMBER=NNMXARTX                                           
  805. //NNMXLIST EXEC NNCCL,MEMBER=NNMXLIST                                           
  806. //NNMXTX   EXEC NNCCL,MEMBER=NNMXTX                                             
  807. //*                                                                             
  808. //* Link NNMVS load module.  Like SMP/E, expect return code 8 when              
  809. //* doing this from scratch.  Additional one-or-two-module links                
  810. //* will just replace the corresponding parts of the load module.               
  811. //*                                                                             
  812. //NNLINK EXEC NNLINK                                                            
  813. //LKED.SYSLIN DD DISP=(OLD,DELETE),DSN=&&LOADSET                                
  814. //            DD *                                                              
  815.  INCLUDE SYSLMOD(NNMMAIN)             if included first time, RC = 8            
  816.  INCLUDE SYSLIB(AMPZMVSB)             include if TCP/IP V1 only                 
  817.  ENTRY   CEESTART                                                               
  818.  NAME    NNMMAIN(R)                                                             
  819. /*                                                                              
  820. ./   ADD NAME=GRAMMAR,SSI=01030032                                              
  821.                                                                                 
  822.         Grammar for NNMVS batch mode expressions.                               
  823.                                                                                 
  824. /*-------------------------------------------------------------------*/         
  825.                                                                                 
  826. exp         :       choice                                                      
  827.             :       "IF" exp "THEN" exp "ELSE" exp                              
  828.                                        /* IF flag THEN any ELSE any */          
  829.                                                                                 
  830. choice      :       relation                                                    
  831.             :       choice logop relation   /* flag | flag -> flag  */          
  832.                                                                                 
  833. relation    :       value                                                       
  834.             :       value relop value       /* any > any   -> flag  */          
  835.                                                                                 
  836. value       :       quantity                                                    
  837.             :       quantity quantity       /* any any    -> string */          
  838.                                                                                 
  839. quantity    :       term                                                        
  840.             :       quantity addop term     /* num + num  -> number */          
  841.                                                                                 
  842. term        :       factor                                                      
  843.             :       term mulop factor       /* num * num -> number  */          
  844.                                                                                 
  845. factor      :       constant                                                    
  846.             :       variable                /* FOO, if declared     */          
  847.             :       unop factor             /* - number  -> number  */          
  848.             :       "(" exp ")"             /* (a + b * c > d | e ) */          
  849.                                                                                 
  850. constant    :       number                                                      
  851.             :       string                                                      
  852.             :       flag                                                        
  853.                                                                                 
  854. unop        :       "+"                                                         
  855.             :       "-"                                                         
  856.             :       "!"                                                         
  857.             :       "^"                                                         
  858.                                                                                 
  859. addop       :       "+"                                                         
  860.             :       "-"                                                         
  861.                                                                                 
  862. mulop       :       "*"                                                         
  863.             :       "/"                                                         
  864.                                                                                 
  865. logop       :       "&"                                                         
  866.             :       "|"                                                         
  867.                                                                                 
  868.                                                                                 
  869. relop       :       "="                                                         
  870.             :       ">"                                                         
  871.             :       "<"                                                         
  872.             :       "=="                                                        
  873.             :       ">="                                                        
  874.             :       "<="                                                        
  875.             :       "!="                                                        
  876.             :       "!>"                                                        
  877.             :       "!<"                                                        
  878.             :       "^="                                                        
  879.             :       "^>"                                                        
  880.             :       "^<"                                                        
  881.             :       "IN"                                                        
  882.                                                                                 
  883. variable    :       [a-z]*                                                      
  884.                                                                                 
  885. number      :       [0-9]*                                                      
  886.                                                                                 
  887. string      :       ""...""                                                     
  888.                                                                                 
  889. flag        :       "TRUE"                                                      
  890.             :       "FALSE"                                                     
  891.             :       "ON"                                                        
  892.             :       "OFF"                                                       
  893.             :       "YES"                                                       
  894.             :       "NO"                                                        
  895. ./   ADD NAME=HELP,SSI=010D0043                                                 
  896.                     NNMVS Batch Mode Help                                       
  897.                                                                                 
  898.  The following commands are available:                                          
  899.                                                                                 
  900.  Top-Level Commands (in top-level mode, picking newsgroups)                     
  901.                                                                                 
  902.    FOR ALL | REGISTERED | UNREGISTERED {WHEN filter} commandlist;               
  903.                                                                                 
  904.       where filter is any flag expression, evaluated per newsgroup,             
  905.       and commandlist is a single command or DO; commands; END;                 
  906.       and the commands are per-newsgroup commands.                              
  907.                                                                                 
  908.  Per-Newsgroup Commands (in newsgroup mode, picking articles)                   
  909.                                                                                 
  910.    REGISTER                                                                     
  911.    DEREGISTER                                                                   
  912.    EXTRACT ALL | READ | UNREAD                                                  
  913.    QUERY                                                                        
  914.    FOR ALL | READ | UNREAD | num {TO num} {WHEN filter} commandlist             
  915.                                                                                 
  916.       where filter is any flag expression, evaluated per article,               
  917.       and commandlist is a single command or DO; commands; END                  
  918.       and the commands are per-article commands.                                
  919.                                                                                 
  920.  Per-Article Commands (in article mode)                                         
  921.                                                                                 
  922.    MARK {READ | UNREAD}                                                         
  923.    LIST                                                                         
  924.    EXTRACT                                                                      
  925.    QUERY                                                                        
  926.                                                                                 
  927.  Miscellaneous Commands                                                         
  928.                                                                                 
  929.    IF condition THEN commandlist; {ELSE commandlist;}                           
  930.                                                                                 
  931.       where condition is any flag expression,                                   
  932.       and commandlist is a single command or DO; commands; END;                 
  933.       and the commands are of the same mode as the one in which                 
  934.       the IF occurs.                                                            
  935.                                                                                 
  936.    PUT stringexpression               # writes to output file                   
  937.    EXEC stringexpression              # executes system command         /       
  938.    NNTP stringexpression              # transmits NNTP request          /       
  939.    QUIT                               # terminates NNMVS                        
  940.    VARS                               # dumps current variables                 
  941.                                                                                 
  942.    {SET} variable { = } expression                                              
  943.                                                                                 
  944.      Variable must be builtin or declared (see DECLARE below)                   
  945.                                                                                 
  946.    DECLARE variable {STRING | NUMBER | FLAG}                                    
  947.                                                                                 
  948.      Note:  DECLARE is the only command which is executed immediately.          
  949.             All other commands are parsed and then the entire command           
  950.             stream is executed only if no errors were detected.                 
  951.                                                                                 
  952.  Built-in Variables                                                             
  953.                                                                                 
  954.  LOCALPATH (string)  - the hosts's local path name                              
  955.  DATETIME  (string)  - a time stamp                                             
  956.  SERVER    (string)  - the name of the NNTP server host.  Must be set           
  957.                        by the user before attempting a connection.              
  958.  OUTFILE   (string)  - the name of an alternate output file for the             
  959.                        PUT commands and any commands (like NNTP) that           
  960.                        write text.  The default setting, "", uses the           
  961.                        NNBATOUT DD.  The value may be a data set name           
  962.                        (appended to) or in the form DD:ddname.                  
  963.  SERVERLIST (flag)   - default is TRUE.  Normally NNMVS will ask for            
  964.                        the current list of newsgroups from the NNTP             
  965.                        server when it begins processing newsgroups.             
  966.                        If you want to suppress this and just use the            
  967.                        groups named in NEWSRC, set SERVERLIST to FALSE.         
  968.                        Note that this may not save time, and in fact            
  969.                        may result in more processing, since NNMVS will          
  970.                        issue a GROUP request to each group requested            
  971.                        when it has not issued a LIST request.                   
  972.  AUTOREGISTER (flag) - default is FALSE.  If this is set to TRUE,               
  973.                        new newsgroups will automatically be registered          
  974.                        in the NEWSRC file; otherwise they will be added         
  975.                        as unregistered newsgroups.                              
  976.  AUTODELETE   (flag) - default is TRUE.  If this is set to TRUE,                
  977.                        bogus newsgroups (groups in the NEWSRC file that         
  978.                        are not known to the server) will be deleted             
  979.                        from the NEWSRC file.  Set this to FALSE to keep         
  980.                        such newsgroups in NEWSRC anyway.                        
  981.  ERROR        (flag) - set to TRUE whenever an NNMVS batch command              
  982.                        operation fails.  This is reset by each NNMVS            
  983.                        batch command, so grab it early.                         
  984.  EXACTCASE    (flag) - default is FALSE.  When this is FALSE, string            
  985.                        comparisons and tests succeed regardless of upper        
  986.                        or lower case.  When this is set to TRUE, string         
  987.                        comparisons and tests succeed only if the strings        
  988.                        match exactly.  Thus, "a" = "A" when EXACTCASE is        
  989.                        FALSE, but not when EXACTCASE is TRUE.                   
  990.                                                                                 
  991.  Variables meaningful to the EXTRACT command:                                   
  992.                                                                                 
  993.  TABEXPAND    (flag) - default is TRUE.  Controls whether tab characters        
  994.                        are to be expanded on EXTRACT.  (Note that tabs          
  995.                        are always expanded on PUT and LIST.)                    
  996.  APPEND       (flag) - default is TRUE.  Controls how articles are to be        
  997.                        extracted to sequential files by EXTRACT.                
  998.                        If APPEND is set to FALSE, existing sequential           
  999.                        files will be overwritten.  This option is not           
  1000.                        applicable to partitioned data sets (PDS's).             
  1001.  SEPARATOR  (string) - default is the null string.  If this is set to           
  1002.                        a value other than the null string, the value            
  1003.                        will be written between articles as a separator          
  1004.                        line.  Meaningful only when APPEND is TRUE.              
  1005.  BLANKSEP     (flag) - default is FALSE.  If TRUE, a blank line will be         
  1006.                        generated before the separator line when it us           
  1007.                        written out between articles.  Otherwise the             
  1008.                        separator line, if used, will follow the end of          
  1009.                        the preceding article immediately.  Meaningful           
  1010.                        only when SEPARATOR and APPEND are set.                  
  1011.  AUTOMARK     (flag) - default is TRUE.  When this is TRUE, the EXTRACT         
  1012.                        operation will mark unread articles READ upon            
  1013.                        successful extraction.  It has no effect on              
  1014.                        read articles or articles that failed extraction.        
  1015.                        Set it to FALSE to prevent EXTRACT from marking          
  1016.                        extracted articles read.                                 
  1017.                                                                                 
  1018.  Variables meaningful in per-newsgroup mode and modes below:                    
  1019.                                                                                 
  1020.  GROUP      (string) - the name of the current newsgroop.                       
  1021.  REGISTERED (flag)   - TRUE if newsgroup is registered.                         
  1022.  NEWGROUP   (flag)   - TRUE if newsgroup is a new group (found by the           
  1023.                        server LIST request but not in NEWSRC).                  
  1024.  NOSUCHGROUP (flag)  - TRUE if the newsgroup is "bogus" (in NEWSRC but          
  1025.                        not found by the server LIST request).                   
  1026.  COUNT      (number) - the total number of articles in the newsgroup.           
  1027.  UNREAD     (number) - the total number of new (unread) articles in the         
  1028.                        newsgroup since the last time NNMVS used this            
  1029.                        NEWSRC file.                                             
  1030.  FIRST      (number) - the number of the first article in the group.            
  1031.  LAST       (number) - the number of the last article in the group.             
  1032.                                                                                 
  1033.  Variables meaningful in per-article mode and modes below:                      
  1034.                                                                                 
  1035.  NUMBER     (number) - the current article number.                              
  1036.  READ       (flag)   - TRUE if article has already been read.                   
  1037.  MISSING    (flag)   - TRUE if article cannot be retrieved from server.         
  1038.  SUBJECT    (string) - text of the Subject: header.                             
  1039.  DATE       (string) - text of the Date: header, with day name removed.         
  1040.  FROM       (string) - text of From: header, author of the article.             
  1041.  MESSAGEID  (string) - text of the Message-ID: header.                          
  1042.                                                                                 
  1043.  Expression Syntax                                                              
  1044.                                                                                 
  1045.  Expressions can be string expressions, number expressions, or                  
  1046.  flag expressions.  They can contain constants, variables, and                  
  1047.  arithmetic or logical expressions.  Strings may be concatenated                
  1048.  by placing one next to another, e. g. "foo" "bar".                             
  1049.                                                                                 
  1050.  String constants are enclosed in double quotes, with the backslash             
  1051.  acting as an escape with which to enclose embedded double quotes.              
  1052.                                                                                 
  1053.  Numeric constants are integers only.                                           
  1054.                                                                                 
  1055.  Flag constants may be represented as TRUE FALSE ON OFF YES NO.                 
  1056.                                                                                 
  1057.  Arithmetic operators:  + - * / as well as unary + and -                        
  1058.  Logical    operators:  & |     as well as unary !                              
  1059.  Relational operators:  = != > < >= <= !> !<                                    
  1060.  (Note: == is an alias for =, and ^ may be used wherever ! is.)                 
  1061.                                                                                 
  1062.  For strings, the additional relational operator IN is available, e.g.          
  1063.                                                                                 
  1064.    "foo" IN SUBJECT                                                             
  1065.                                                                                 
  1066.  The notation (IF expression THEN expression ELSE expression) is                
  1067.  allowed within expressions.                                                    
  1068.                                                                                 
  1069.  The following synonyms are accepted:                                           
  1070.                                                                                 
  1071.    AND OR NOT EQ NE GT LT GE LE NG NL                                           
  1072.                                                                                 
  1073.  The character # marks the beginning of a comment.                              
  1074.                                                                                 
  1075. Extracting Files                                                                
  1076.                                                                                 
  1077.  EXTRACT writes the contents of one or more news articles out to a file         
  1078.  whose name is determined from a table allocated to DDname NNEXTTAB.            
  1079.                                                                                 
  1080.  The format of the extract table is one line per newsgroup as follows:          
  1081.                                                                                 
  1082.   groupname filename                                                            
  1083.                                                                                 
  1084.  where filename is a FULLY QUALIFIED name (quotes ignored) of one of            
  1085.  the following formats:                                                         
  1086.                                                                                 
  1087.   sequential data set name                                                      
  1088.   wildcarded sequential data set name                                           
  1089.   wildcarded partitioned data set name                                          
  1090.                                                                                 
  1091.  "Wildcarded" means that there is an asterisk "*" in a strategic                
  1092.  position in the file name.  It must be preceded by at least one                
  1093.  alphanumeric character and may not be followed by one.                         
  1094.                                                                                 
  1095.  When the extraction is done, the asterisk is replaced with the number          
  1096.  of the article, zero padded on the left to fill out that segment of            
  1097.  the name.                                                                      
  1098.                                                                                 
  1099.  Examples:                                                                      
  1100.                                                                                 
  1101.   comp.group.one   MYID.COMP.GROUP.SEQ.FOO*                                     
  1102.   comp.group.two   MYID.COMP.GROUP.SEQ.ALL                                      
  1103.   comp.group.three MYID.COMP.GROUP.THREE.PDS(X*)                                
  1104.   comp.group.four  MYID.COMP.GROUP.NUMBER*.PDS(ANYMEM)                          
  1105.                                                                                 
  1106.  So...                                                                          
  1107.                                                                                 
  1108.   comp.windows.x  SEB1525.COMP.WINDOWS.X.TEXT.#*                                
  1109.                                                                                 
  1110.  defines a series of sequential data sets                                       
  1111.  COMP.WINDOWS.X.TEXT.#0000001                                                   
  1112.  COMP.WINDOWS.X.TEXT.#0000002                                                   
  1113.                                                                                 
  1114.  etc.                                                                           
  1115.                                                                                 
  1116.  PDS members can be expressed this way:                                         
  1117.                                                                                 
  1118.   comp.os.vms     COMP.OS.VMS.PDS(VMS*)                                         
  1119.                                                                                 
  1120.  which gives                                                                    
  1121.                                                                                 
  1122.   COMP.OS.VMS.PDS(VMS00001)                                                     
  1123.   COMP.OS.VMS.PDS(VMS00002)                                                     
  1124.                                                                                 
  1125.  etc.  If the article number takes more digits, it steals some                  
  1126.  character positions away from the characters immediately preceding             
  1127.  the asterisk.  For example, using the above model:                             
  1128.                                                                                 
  1129.   COMP.OS.VMS.PDS(VM142857)                                                     
  1130.                                                                                 
  1131.  The file need not already exist.  If it does not, NNMVS will attempt           
  1132.  to guess the appropriate size when it allocates it, as the EXTRACT             
  1133.  command does in foreground.                                                    
  1134.                                                                                 
  1135. ./   ADD NAME=NNMVS,SSI=01030000                                                
  1136. //*                                                                  */         
  1137. //* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  1138. //*                                                                  */         
  1139. //* This software is provided on an "AS IS" basis.  All warranties,  */         
  1140. //* including the implied warranties of merchantability and fitness, */         
  1141. //* are expressly denied.                                            */         
  1142. //*                                                                  */         
  1143. //* Provided this copyright notice is included, this software may    */         
  1144. //* be freely distributed and not offered for sale.                  */         
  1145. //*                                                                  */         
  1146. //* Changes or modifications may be made and used only by the maker  */         
  1147. //* of same, and not further distributed.  Such modifications should */         
  1148. //* be mailed to the author for consideration for addition to the    */         
  1149. //* software and incorporation in subsequent releases.               */         
  1150. //*                                                                  */         
  1151. //NNMVS    PROC DEBUG=,                 say DEBUG=D for debugging               
  1152. //             LOADLIB='NNMVS.LOAD',    must match LOADLIB in LINK job          
  1153. //             HELP='NNMVS.HELP',              for batch HELP command           
  1154. //             NEWSRC='USERID.BATCH.NEWSRC',   separate NEWSRC file             
  1155. //             EXTTAB='USERID.NNMVS.EXTTAB'    table used by EXTRACT            
  1156. //*                                                                             
  1157. //* NNMVS batch mode.                                                           
  1158. //*                                                                             
  1159. //NN       EXEC PGM=NNMMAIN,PARM='-B&DEBUG'                                     
  1160. //STEPLIB  DD   DISP=SHR,DSN=&LOADLIB                                           
  1161. //NNNEWSRC DD   DISP=OLD,DSN=&NEWSRC                                            
  1162. //NNEXTTAB DD   DISP=SHR,DSN=&EXTTAB                                            
  1163. //NNBATHLP DD   DISP=SHR,DSN=&HELP                                              
  1164. //SYSPRINT DD   SYSOUT=*                                                        
  1165. //SYSERR   DD   SYSOUT=*                                                        
  1166. //NNBATOUT DD   SYSOUT=*,DCB=(RECFM=VB,LRECL=255)                               
  1167. //NNDEBUG  DD   SYSOUT=*                                                        
  1168. //NNBATIN  DD   DDNAME=SYSIN                                                    
  1169. //*                                                                             
  1170. //         PEND NNMVS                                                           
  1171. ./   ADD NAME=NNMVSHLP,SSI=01020018                                             
  1172. )F Function -                                                                   
  1173.                                                                                 
  1174.  NNMVS is a newsreader for reading and posting articles in USENET               
  1175.  newsgroups.                                                                    
  1176.                                                                                 
  1177.  NNMVS is an NNTP (network news transfer protocol) client that accesses         
  1178.  USENET news from a host machine elsewhere on your network that is              
  1179.  running an NNTP news server, and displays the news via ISPF.  You must         
  1180.  tell NNMVS where this news server is; it does not know otherwise.              
  1181.                                                                                 
  1182.  NNMVS remembers which articles you have read in a "newsrc" data set.           
  1183.  You specify the name of this data set on the primary menu, along               
  1184.  with the name of the news server host.  Note that both of these                
  1185.  are given useful defaults when you start up NNMVS.                             
  1186.                                                                                 
  1187.  If you have never used NNMVS before, you use the blank or L option to          
  1188.  build up your NEWSRC file from a list retrieved from the server.               
  1189.  Then, to limit the list to your favorite newsgroups, you can register          
  1190.  (subscribe to) the ones you want while viewing the newsgroup list.             
  1191.                                                                                 
  1192.  You can use L or blank all the time to enter NNMVS.  However,                  
  1193.  once you have used and built a NEWSRC file, you may wish to use a              
  1194.  different entry option to reduce startup time.                                 
  1195.  You can avoid retrieving the whole list by using the R option                  
  1196.  to view only registered (subscribed) newsgroups, or the A option to            
  1197.  view all newsgroups listed in your NEWSRC file.                                
  1198.                                                                                 
  1199.  The disadvantage to using A or R is that you do not get the latest             
  1200.  additions to the news system when the newsgroup list shows up.                 
  1201.  But there are ways to get around this.  For example, you can use the           
  1202.  N option to get a list of newsgroups added since the last time you             
  1203.  retrieved the newsgroup list (i.e. used L or N).                               
  1204.                                                                                 
  1205.  If you want to go to a particular newsgroup directly, you can do so            
  1206.  via the G option.  When you use this, you must provide the name of             
  1207.  the desired newsgroup.                                                         
  1208.                                                                                 
  1209. )I NNMVSLOC          - local NNMVS help goes in member NNMVSLOC                 
  1210.                                                                                 
  1211. )X Syntax -                                                                     
  1212.                                                                                 
  1213.    %NNMVS                                                                       
  1214.               SERVER('news server host')                                        
  1215.               GROUP('newsgroup name')                                           
  1216.               NEWSRC('data set name')                                           
  1217.               OPTION(A/G/L/N/O/P/R/X)                                           
  1218.               REGISTERSTATUS(Yes/No/Prompt)                                     
  1219.               FORCE                                                             
  1220.               DEBUG                                                             
  1221.               TEST                                                              
  1222.               BATCH                                                             
  1223.               BATCHIN('batch input file name')                                  
  1224.               BATCHOUT('batch output file name')                                
  1225.               NEW                                                               
  1226.               OLD                                                               
  1227.                                                                                 
  1228.    Required:  none                                                              
  1229.                                                                                 
  1230.    Defaults:  User is prompted (via ISPF panel) for all omitted values          
  1231.                                                                                 
  1232.    Notes:     If OPTION is given, then direct entry into the news               
  1233.               reader occurs, without display of the NNMVS primary menu.         
  1234.               However, if so, then SERVER and NEWSRC are required, and          
  1235.               GROUP is also required if OPTION(G) is specified.                 
  1236.                                                                                 
  1237.               If BATCH is given, then NEWSRC is required.                       
  1238.                                                                                 
  1239. )O Operands -                                                                   
  1240.                                                                                 
  1241. ))SERVER('news server host')                                                    
  1242.                                                                                 
  1243.               The hostname of the machine running the news server.              
  1244.               Note that an IP address may be specified, but this                
  1245.               is obviously not recommended.                                     
  1246.                                                                                 
  1247.               If an asterisk "*" is specified as the server name,               
  1248.               an experimental dialog is invoked which displays an               
  1249.               ISPF table of news servers with associated NEWSRC                 
  1250.               data set names.  You select the news server you want              
  1251.               (or add a line associating that server with a specific            
  1252.               NEWSRC file).  This feature is courtesy of Leonard Woren          
  1253.               (LDW@MVSA.USC.EDU, SHARE installation code USC).                  
  1254.                                                                                 
  1255. ))GROUP('newsgroup name')                                                       
  1256.                                                                                 
  1257.               The name of a specific newsgroup you want to see,                 
  1258.               rather than the list of all newsgroups.  If you specify           
  1259.               this, it will merely fill in the corresponding field of           
  1260.               the NNMVS primary menu, unless you also specify the               
  1261.               keyword OPTION(G) and values for SERVER and NEWSRC.               
  1262.                                                                                 
  1263. ))NEWSRC('data set name')                                                       
  1264.                                                                                 
  1265.               The name of your "newsrc" file, a sequential data set             
  1266.               which keeps track of which articles you've already read           
  1267.               in which newsgroups.  If this data set does not exist,            
  1268.               NNMVS will create it.                                             
  1269.                                                                                 
  1270.               It is a good idea to use the same NEWSRC file all the             
  1271.               time for one news server, but to use separate NEWSRC              
  1272.               files for different news servers (should there be any).           
  1273.                                                                                 
  1274.               If you specify this, it will merely fill in the                   
  1275.               corresponding field of the NNMVS primary menu, unless             
  1276.               you also specify values for SERVER and OPTION.                    
  1277.                                                                                 
  1278.               If an asterisk "*" is specified as the NEWSRC name,               
  1279.               an experimental dialog is invoked which displays an               
  1280.               ISPF table of news servers with associated NEWSRC                 
  1281.               data set names.  You select the news server you want              
  1282.               (or add a line associating that server with a specific            
  1283.               NEWSRC file).  This feature is courtesy of Leonard Woren          
  1284.               (LDW@MVSA.USC.EDU, SHARE installation code USC).                  
  1285.                                                                                 
  1286. ))OPTION(A/G/L/N/O/P/R/X)                                                       
  1287.                                                                                 
  1288.               The initial option to start up NNMVS without seeing               
  1289.               the primary menu, where the meanings of the letters               
  1290.               are those as displayed on the menu:                               
  1291.                                                                                 
  1292.               L - List all newsgroups from server                               
  1293.               N - List new newsgroups from server since last N or L             
  1294.               A - Show items from all newsgroups listed in NEWSRC file          
  1295.               R - Show items from registered newsgroups in NEWSRC file          
  1296.               G - Go directly to the newsgroup named by operand GROUP           
  1297.               P - Enter native NNTP protocol commands                           
  1298.               O - Specify NNMVS options defaults                                
  1299.               X - Exit NNMVS                                                    
  1300.                                                                                 
  1301.               If you specify this, you must also specify values for             
  1302.               SERVER and NEWSRC.  Also, if you specify OPTION(G), you           
  1303.               must provide a value for the GROUP keyword.                       
  1304.                                                                                 
  1305. ))REGISTERSTATUS(Yes/No/Prompt)                                                 
  1306.                                                                                 
  1307.               When you specify OPTION(R), NNMVS decides whether to              
  1308.               get the current status of each registered newsgroup,              
  1309.               since it doesn't get that information for free as it              
  1310.               does when you use the "L" (list) option.  Therefore,              
  1311.               it normally prompts you with a popup asking you if it             
  1312.               is OK to do this, since it takes time.                            
  1313.                                                                                 
  1314.               Specify REGISTERSTATUS(Y) to tell NNMVS to go ahead and           
  1315.               do this.  REGISTERSTATUS(N) says not to.  The default,            
  1316.               REGISTERSTATUS(P), tells NNMVS to prompt as it would if           
  1317.               you selected option R from the primary menu.                      
  1318.                                                                                 
  1319. ))FORCE                                                                         
  1320.                                                                                 
  1321.               NNMVS tries to determine if there is a TCP/IP socket              
  1322.               application active elsewhere in your TSO environment              
  1323.               before starting up, to prevent TCP/IP errors.  If it              
  1324.               tells you that there is another client active but in              
  1325.               truth there is none and you know it, you can use the              
  1326.               FORCE keyword to make NNMVS proceed whether it finds              
  1327.               this to be the case or not.                                       
  1328.                                                                                 
  1329. ))DEBUG                                                                         
  1330.                                                                                 
  1331.               Set debugging mode on.  You must preallocate a file to            
  1332.               ddname NNDEBUG for this to work.  This can be allocated           
  1333.               to the terminal or a log file.  When debug mode is on,            
  1334.               messages describing memory allocation and deallocation            
  1335.               and NNTP commands sent are dumped to the debug file.              
  1336.                                                                                 
  1337. ))TEST                                                                          
  1338.                                                                                 
  1339.               Activate C/370 interactive test (INSPECT).  NNMVS must            
  1340.               have been compiled with the TEST option for this to be            
  1341.               effective.  Note that you can also issue the TEST command         
  1342.               inside NNMVS to get to INSPECT, again provided that NNMVS         
  1343.               was compiled with the TEST option.                                
  1344. ))BATCH                                                                         
  1345.                                                                                 
  1346.               Invoke NNMVS in batch mode.  When BATCH is specified,             
  1347.               NEWSRC must also be specified.  The files specified by            
  1348.               BATCHIN and BATCHOUT are allocated and you supply                 
  1349.               NNMVS batch commands in the BATCHIN file (typically the           
  1350.               terminal).  You specify the news server via the command           
  1351.                                                                                 
  1352.               server = "foobar";                                                
  1353.                                                                                 
  1354.               where foobar should be replaced with the actual name of           
  1355.               the NNTP server host.                                             
  1356.                                                                                 
  1357.               Note that no batch commands will be executed until the            
  1358.               entire batch language program is read in and EOF is met.          
  1359.                                                                                 
  1360.               For help with the batch language, execute NNMVS in batch          
  1361.               mode and supply the command "HELP".                               
  1362.                                                                                 
  1363. ))BATCHIN('batch input file name')                                              
  1364.                                                                                 
  1365.               the data set allocated for input to NNMVS batch mode.             
  1366.               Default is * (the terminal).                                      
  1367.                                                                                 
  1368.               Note that no batch commands will be executed until the            
  1369.               entire batch language program is read in and EOF is met.          
  1370.                                                                                 
  1371.               For help with the batch language, execute NNMVS in batch          
  1372.               mode and supply the command "HELP".                               
  1373.                                                                                 
  1374. ))BATCHOUT('batch output file name')                                            
  1375.                                                                                 
  1376.               the data set allocated for output from NNMVS batch mode.          
  1377.               Default is * (the terminal).                                      
  1378.                                                                                 
  1379.               For help with the batch language, execute NNMVS in batch          
  1380.               mode and supply the command "HELP".                               
  1381.                                                                                 
  1382. ))NEW                                                                           
  1383.                                                                                 
  1384.               Use a new (testing) release of NNMVS.  This is dependent          
  1385.               upon your installation's procedures for providing                 
  1386.               parallel releases of software for users to run online in          
  1387.               test mode.                                                        
  1388.                                                                                 
  1389. ))OLD                                                                           
  1390.                                                                                 
  1391.               Use an old (backup) release of NNMVS.  This is dependent          
  1392.               upon your installation's procedures for providing                 
  1393.               parallel releases of software for users to run online in          
  1394.               test mode.                                                        
  1395.                                                                                 
  1396. ./   ADD NAME=SIGFAIL,SSI=01010054                                              
  1397.                                                                                 
  1398. #include <stdio.h>                                                              
  1399. #include <stdlib.h>                                                             
  1400. #include <signal.h>                                                             
  1401.                                                                                 
  1402. static void                                                                     
  1403. handler() {                                                                     
  1404.  printf("SIGINT handler has been called.\n");                                   
  1405.  exit(8);                                                                       
  1406. }                                                                               
  1407.                                                                                 
  1408. static int                                                                      
  1409. ask(question)                                                                   
  1410. char *question;                                                                 
  1411. {                                                                               
  1412.  char ans[81];                                                                  
  1413.                                                                                 
  1414.  for (;;) {                                                                     
  1415.    printf("%s",question);                                                       
  1416.    fgets(ans,79,stdin);                                                         
  1417.    switch (ans[0]) {                                                            
  1418.      case 'y':                                                                  
  1419.      case 'Y': return 1;                                                        
  1420.      case 'n':                                                                  
  1421.      case 'N': return 0;                                                        
  1422.      default: printf("Bad answer, %s\n",ans);                                   
  1423.               continue;                                                         
  1424.    }                                                                            
  1425.  }                                                                              
  1426. }                                                                               
  1427.                                                                                 
  1428. main(argc,argv)                                                                 
  1429. int argc;                                                                       
  1430. char **argv;                                                                    
  1431. {                                                                               
  1432.  int sigp;                                                                      
  1433.  int loopp;                                                                     
  1434.  int i;                                                                         
  1435.                                                                                 
  1436.  printf(                                                                        
  1437.   "This program demonstrates that SIGINT is not handled on MVS.\n");            
  1438.  printf(                                                                        
  1439.   "It does NOT prove or disprove anything about attention handling\n");         
  1440.  printf(                                                                        
  1441.   "in C/370 in general, except possibly for how output to stdout\n");           
  1442.  printf(                                                                        
  1443.   "and stderr are affected by an attention interruption.\n\n");                 
  1444.  printf(                                                                        
  1445.   "At the end of the program, a line of output is written to each\n");          
  1446.  printf(                                                                        
  1447.   "of the two output files.  If you see either one, that means that\n");        
  1448.  printf(                                                                        
  1449.   "C/370 has intercepted the attention, but you will observe that\n");          
  1450.  printf(                                                                        
  1451.   "it has not been handled by a SIGINT routine and it also has not\n");         
  1452.  printf(                                                                        
  1453.   "allowed the program to be terminated by the operating system.\n\n");         
  1454.                                                                                 
  1455.  sigp  = ask("Do you want to signal abort on interrupts? (y or n)");            
  1456.  loopp = ask("Do you want to loop forever without output? (y or n)");           
  1457.                                                                                 
  1458.  if (sigp) {                                                                    
  1459.    printf("Doing signal(SIGINT,handler)\n");                                    
  1460.    if (signal(SIGINT,handler) == SIG_ERR)                                       
  1461.        perror("Could not set SIGINT");                                          
  1462.  }                                                                              
  1463.                                                                                 
  1464.  printf("OK, hit PA1 now\n");                                                   
  1465.                                                                                 
  1466.  if (loopp) {                                                                   
  1467.    for (;;) ;                                                                   
  1468.  }                                                                              
  1469.  else {                                                                         
  1470.    for (i=0;i<5000;i++) {                                                       
  1471.     printf("I=%d\n",i);                                                         
  1472.    }                                                                            
  1473.  }                                                                              
  1474.  printf("I'm finished (on stdout)\n");                                          
  1475.  fprintf(stderr,"I'm finished (on stderr)\n");                                  
  1476. }                                                                               
  1477.                                                                                 
  1478. ./ ENDUP                                                                        
  1479. ?!                                                                              
  1480. //C        EXEC NNLOAD,TRK1='42',TO='C'                                         
  1481. //SYSIN    DD DATA,DLM='?!'                                                     
  1482. ./   ADD NAME=NNMADDNG,SSI=01220038                                             
  1483.                                                                                 
  1484.  /********************************************************************/         
  1485.  /*                                                                  */         
  1486.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  1487.  /*                                                                  */         
  1488.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  1489.  /* including the implied warranties of merchantability and fitness, */         
  1490.  /* are expressly denied.                                            */         
  1491.  /*                                                                  */         
  1492.  /* Provided this copyright notice is included, this software may    */         
  1493.  /* be freely distributed and not offered for sale.                  */         
  1494.  /*                                                                  */         
  1495.  /* Changes or modifications may be made and used only by the maker  */         
  1496.  /* of same, and not further distributed.  Such modifications should */         
  1497.  /* be mailed to the author for consideration for addition to the    */         
  1498.  /* software and incorporation in subsequent releases.               */         
  1499.  /*                                                                  */         
  1500.  /********************************************************************/         
  1501.                                                                                 
  1502. #pragma  csect(code,  "NN@ADDNG")                                               
  1503. #pragma  csect(static,"NN$ADDNG")                                               
  1504.                                                                                 
  1505. #include "nn.h"                                                                 
  1506.                                                                                 
  1507. #define KEEP_NEWSGROUPS_IN_ALPHABETICAL_ORDER                                   
  1508.                                                                                 
  1509. /****** Create a new newsgroup. **************************************/         
  1510.                                                                                 
  1511. static struct newsgroup *                                                       
  1512. new_newsgroup(np,gname)                                                         
  1513. Rstruc nncb         *np;                                                        
  1514. char                *gname;                                                     
  1515. {                                                                               
  1516.  struct newsgroup   *gp;                                                        
  1517.  char                temp[sizeof(gp->name) + 16];                               
  1518.                                                                                 
  1519.                                                                                 
  1520.                                                                                 
  1521.  sprintf(temp, "newsgroup %s", gname);                                          
  1522.  GETMAIN(gp, char,                                                              
  1523.              offsetof(struct newsgroup, name) + strlen(gname) + 1,              
  1524.              temp);                                                             
  1525.                                                                                 
  1526.  if (gp == NULL) {                                                              
  1527.    ERR1("There is not enough virtual storage to add a newsgroup.");             
  1528.    return NULL;                                                                 
  1529.  }                                                                              
  1530.                                                                                 
  1531.  strcpy(gp->name,gname);                                                        
  1532.  ClearGroupStatus(gp);                                                          
  1533.  gp->next                       = NULL;                                         
  1534.  gp->next2                      = NULL;                                         
  1535.  gp->fake_article_count         = 0;                                            
  1536.  gp->real_article_count         = NO_VALUE;                                     
  1537.  gp->fake_first_article_number  = 0;                                            
  1538.  gp->real_first_article_number  = NO_VALUE;                                     
  1539.  gp->fake_last_article_number   = 0;                                            
  1540.  gp->real_last_article_number   = NO_VALUE;                                     
  1541.  gp->fake_unread_count          = 0;                                            
  1542.  gp->real_unread_count          = NO_VALUE;                                     
  1543.  gp->registered                 = 0;                                            
  1544.  gp->first_article              = NULL;                                         
  1545.  gp->fake_last_article          = NULL;                                         
  1546.  gp->real_last_article          = NULL;                                         
  1547.  gp->article_vector             = NULL;                                         
  1548.  gp->article_vector_len         = 0;                                            
  1549.  gp->saved_newsrc_line          = NULL;                                         
  1550.                                                                                 
  1551.  np->last_added_newsgroup = gp;                                                 
  1552.                                                                                 
  1553.  return gp;                                                                     
  1554.                                                                                 
  1555. }                                                                               
  1556.                                                                                 
  1557. /****** Add newsgroup. ***********************************************/         
  1558.                                                                                 
  1559. struct newsgroup *                                                              
  1560. NNMaddng(np,gname)                                                              
  1561. Rstruc nncb         *np;                                                        
  1562. char                *gname;                                                     
  1563. {                                                                               
  1564.  Rstruc newsgroup   *gp;                                                        
  1565.  struct newsgroup   *prev_gp;                                                   
  1566.  struct newsgroup   *next_gp;                                                   
  1567.  int                 s;                                                         
  1568.                                                                                 
  1569.  /* If there are no newsgroups yet, make this the first one.       */           
  1570.  /* If the newsgroup is currently in the newsgroup list, reuse it. */           
  1571.  /* Otherwise add it. */                                                        
  1572.                                                                                 
  1573.  if (np->first_newsgroup == NULL) {                                             
  1574.    if ((gp=new_newsgroup(np,gname))) {                                          
  1575.      np->first_newsgroup   = gp;                                                
  1576.      np->current_newsgroup = gp;                                                
  1577.      np->last_newsgroup    = gp;                                                
  1578.    }                                                                            
  1579.    return gp;                                                                   
  1580.  }                                                                              
  1581.                                                                                 
  1582.  prev_gp = NULL;                                                                
  1583.  next_gp = NULL;                                                                
  1584.                                                                                 
  1585.                                                                                 
  1586. #ifdef KEEP_NEWSGROUPS_IN_ALPHABETICAL_ORDER                                    
  1587.                                                                                 
  1588.  /* Chances are this newsgroup will be right after the last one that            
  1589.     we added.  Check there first. */                                            
  1590.                                                                                 
  1591.  gp = np->last_added_newsgroup;         /* search from last added  */           
  1592.  if (!gp || strcmp(gname,gp->name) < 0) /* unless ours precedes it */           
  1593.      gp = np->first_newsgroup;          /* then search from top    */           
  1594.                                                                                 
  1595.  for (; gp; gp = gp->next) {                                                    
  1596.    s = strcmp(gname,gp->name);                                                  
  1597.    if (s == 0)     { /* equal */                                                
  1598.      np->current_newsgroup = gp;                                                
  1599.      return gp;                                                                 
  1600.    }                                                                            
  1601.    else if (s < 0) { /* ours is less than theirs */                             
  1602.      next_gp = gp;                                                              
  1603.      break;                                                                     
  1604.    }                                                                            
  1605.    else            { /* ours is still greater */                                
  1606.      prev_gp = gp;                                                              
  1607.      next_gp = NULL;                                                            
  1608.    }                                                                            
  1609.  }                                                                              
  1610.                                                                                 
  1611. #else                                                                           
  1612.                                                                                 
  1613.  /* keep newsgroups in NEWSRC order - not currently implemented */              
  1614.                                                                                 
  1615.  for (gp = np->first_newsgroup;                                                 
  1616.       gp && strcmp(gname,gp->name) != 0;                                        
  1617.       gp = gp->next) ;                                                          
  1618.                                                                                 
  1619.  if (gp) {   /* newsgroup already in list */                                    
  1620.    np->current_newsgroup = gp;                                                  
  1621.    return gp;                                                                   
  1622.  }                                                                              
  1623.                                                                                 
  1624.  next_gp = NULL;                                                                
  1625.  prev_gp = np->last_newsgroup;                                                  
  1626.                                                                                 
  1627. #endif                                                                          
  1628.                                                                                 
  1629.  /* newsgroup not in list - add it now */                                       
  1630.                                                                                 
  1631.  if ((gp=new_newsgroup(np,gname))) {                                            
  1632.                                                                                 
  1633.    if (next_gp == NULL) np->last_newsgroup = gp;                                
  1634.    else                 gp->next = next_gp;                                     
  1635.    if (prev_gp == NULL) np->first_newsgroup = gp;                               
  1636.    else                 prev_gp->next = gp;                                     
  1637.                                                                                 
  1638.    np->current_newsgroup = gp;                                                  
  1639.  }                                                                              
  1640.                                                                                 
  1641.  return gp;                                                                     
  1642. }                                                                               
  1643.                                                                                 
  1644. ./   ADD NAME=NNMADJUA,SSI=010E0057                                             
  1645.                                                                                 
  1646.  /********************************************************************/         
  1647.  /*                                                                  */         
  1648.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  1649.  /*                                                                  */         
  1650.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  1651.  /* including the implied warranties of merchantability and fitness, */         
  1652.  /* are expressly denied.                                            */         
  1653.  /*                                                                  */         
  1654.  /* Provided this copyright notice is included, this software may    */         
  1655.  /* be freely distributed and not offered for sale.                  */         
  1656.  /*                                                                  */         
  1657.  /* Changes or modifications may be made and used only by the maker  */         
  1658.  /* of same, and not further distributed.  Such modifications should */         
  1659.  /* be mailed to the author for consideration for addition to the    */         
  1660.  /* software and incorporation in subsequent releases.               */         
  1661.  /*                                                                  */         
  1662.  /********************************************************************/         
  1663.                                                                                 
  1664. #pragma  csect(code,  "NN@ADJUA")                                               
  1665. #pragma  csect(static,"NN$ADJUA")                                               
  1666. #include "nn.h"                                                                 
  1667.                                                                                 
  1668. /****** Adjust unread articles. **************************************/         
  1669.                                                                                 
  1670. void                                                                            
  1671. NNMadjua(np,gp,af,al,ac)                                                        
  1672. Rstruc nncb       *np;                                                          
  1673. Rstruc newsgroup  *gp;                                                          
  1674. int                af;  /* estimated first article number */                    
  1675. int                al;  /* estimated last  article number */                    
  1676. int                ac;  /* estimated article count        */                    
  1677. {                                                                               
  1678.  int               i;                                                           
  1679.  VARK             *vp;                                                          
  1680.                                                                                 
  1681.  if (al > gp->fake_last_article_number) {                                       
  1682.    gp->fake_unread_count += (al - gp->fake_last_article_number);                
  1683.    gp->fake_last_article_number = al;                                           
  1684.  }                                                                              
  1685.                                                                                 
  1686.  else if (al < gp->fake_last_article_number) {                                  
  1687.                                                                                 
  1688.    /*                                                                           
  1689.     * Only need to allocate an article vector at this point if                  
  1690.     * al is less than fake_last_article_number - in other words,                
  1691.     * there are fewer articles than we used to think because                    
  1692.     * the most recent articles got cancelled somehow.                           
  1693.     */                                                                          
  1694.                                                                                 
  1695.    if (NNMallav(np,gp)) {          /* Allocate article vector */                
  1696.      for (i = al + 1; i <= gp->fake_last_article_number; i++) {                 
  1697.        vp = &V_STATUS(gp,i);                                                    
  1698.        switch (*vp) {                                                           
  1699.          case V_UNREAD:  *vp = V_MISSING_READ;                                  
  1700.                          gp->fake_unread_count--;                               
  1701.                          break;                                                 
  1702.          case V_READ:    *vp = V_MISSING_READ;                                  
  1703.                          break;                                                 
  1704.        }                                                                        
  1705.      }                                                                          
  1706.    }                                                                            
  1707.  }                                                                              
  1708.                                                                                 
  1709.  if (gp->fake_unread_count > ac) gp->fake_unread_count = ac;                    
  1710.                                                                                 
  1711.  /* Now do adjustments for the low number... */                                 
  1712.  if (af < gp->fake_first_article_number) {                                      
  1713.                                                                                 
  1714.    /*                                                                           
  1715.     * Only need to allocate an article vector at this point if                  
  1716.     * af is greater than fake_first_article_number - in other words,            
  1717.     * there are fewer articles than we used to think because                    
  1718.     * the oldest articles got cancelled or expired.                             
  1719.     */                                                                          
  1720.                                                                                 
  1721.    if (NNMallav(np,gp)) {          /* Allocate article vector */                
  1722.      for (i = af - 1; i >= gp->fake_last_article_number; i--) {                 
  1723.        vp = &V_STATUS(gp,i);                                                    
  1724.        switch (*vp) {                                                           
  1725.          case V_UNREAD:  *vp = V_MISSING_READ;                                  
  1726.                          gp->fake_unread_count--;                               
  1727.                          break;                                                 
  1728.          case V_READ:    *vp = V_MISSING_READ;                                  
  1729.                          break;                                                 
  1730.        }                                                                        
  1731.      }                                                                          
  1732.    }                                                                            
  1733.  }                                                                              
  1734.                                                                                 
  1735.  return;                                                                        
  1736. }                                                                               
  1737.                                                                                 
  1738. ./   ADD NAME=NNMALLAV,SSI=010F0058                                             
  1739.                                                                                 
  1740.  /********************************************************************/         
  1741.  /*                                                                  */         
  1742.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  1743.  /*                                                                  */         
  1744.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  1745.  /* including the implied warranties of merchantability and fitness, */         
  1746.  /* are expressly denied.                                            */         
  1747.  /*                                                                  */         
  1748.  /* Provided this copyright notice is included, this software may    */         
  1749.  /* be freely distributed and not offered for sale.                  */         
  1750.  /*                                                                  */         
  1751.  /* Changes or modifications may be made and used only by the maker  */         
  1752.  /* of same, and not further distributed.  Such modifications should */         
  1753.  /* be mailed to the author for consideration for addition to the    */         
  1754.  /* software and incorporation in subsequent releases.               */         
  1755.  /*                                                                  */         
  1756.  /********************************************************************/         
  1757.                                                                                 
  1758. #pragma  csect(code,  "NN@ALLAV")                                               
  1759. #pragma  csect(static,"NN$ALLAV")                                               
  1760. #include "nn.h"                                                                 
  1761.                                                                                 
  1762. /****** Allocate articles for newsgroup. *****************************/         
  1763.                                                                                 
  1764. Bool                                                                            
  1765. NNMallav(np,gp)                                                                 
  1766. Rstruc nncb            *np;                                                     
  1767. Rstruc newsgroup       *gp;                                                     
  1768. {                                                                               
  1769.  VARK                  *oldvp    = gp->article_vector;                          
  1770.  VARK                  *newvp    = NULL;                                        
  1771.  int                    oldvlen  = gp->article_vector_len;                      
  1772.  int                    newvlen  = gp->fake_last_article_number;                
  1773.  int                    anum;                                                   
  1774.                                                                                 
  1775.  /* This routine allocates a vector of article-readness values.                 
  1776.     If one already exists, this one makes it bigger if necessary.               
  1777.     Otherwise it just returns. */                                               
  1778.                                                                                 
  1779.  if (newvlen < 0) newvlen = 0;                                                  
  1780.                                                                                 
  1781.  if (newvlen <= oldvlen) {                                                      
  1782.    for (anum = newvlen; anum < oldvlen; anum++)                                 
  1783.         oldvp[anum] = V_MISSING_UNREAD;                                         
  1784.    return TRUE;                                                                 
  1785.  }                                                                              
  1786.                                                                                 
  1787.  if (newvlen == 0) return TRUE;                                                 
  1788.                                                                                 
  1789.  GETMAIN(newvp, VARK, newvlen, "article vector");                               
  1790.                                                                                 
  1791.  if (newvp == NULL) {                                                           
  1792.    fprintf(stderr,"Error allocating %d-article vector for %s\n",                
  1793.                   newvlen, gp->name);                                           
  1794.    ERR1("There is not enough virtual memory available to proceed.");            
  1795.    return FALSE;                                                                
  1796.  }                                                                              
  1797.                                                                                 
  1798.  for (anum=0; anum < oldvlen; anum++) newvp[anum] = oldvp[anum];                
  1799.  for (      ; anum < newvlen; anum++) newvp[anum] = V_MISSING_UNREAD;           
  1800.                                                                                 
  1801.  if (oldvlen > 0) FREEMAIN(oldvp,"old article vector");                         
  1802.                                                                                 
  1803.  gp->article_vector     = newvp;                                                
  1804.  gp->article_vector_len = newvlen;                                              
  1805.                                                                                 
  1806.  /* If this is the first time that we have allocated the article                
  1807.   * vector, initialize it from the saved newsrc line if there is one.           
  1808.   * This is applicable if the article vector is being allocated                 
  1809.   * for the first time (GroupListed and GroupSelected should be false).         
  1810.   */                                                                            
  1811.                                                                                 
  1812.  if (oldvlen == 0) NNMpnrl(np,gp);   /* Parse NEWSRC line */                    
  1813.                                                                                 
  1814.  return TRUE;                                                                   
  1815.                                                                                 
  1816. }                                                                               
  1817.                                                                                 
  1818. ./   ADD NAME=NNMALLOC,SSI=01120020                                             
  1819.                                                                                 
  1820.  /********************************************************************/         
  1821.  /*                                                                  */         
  1822.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  1823.  /*                                                                  */         
  1824.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  1825.  /* including the implied warranties of merchantability and fitness, */         
  1826.  /* are expressly denied.                                            */         
  1827.  /*                                                                  */         
  1828.  /* Provided this copyright notice is included, this software may    */         
  1829.  /* be freely distributed and not offered for sale.                  */         
  1830.  /*                                                                  */         
  1831.  /* Changes or modifications may be made and used only by the maker  */         
  1832.  /* of same, and not further distributed.  Such modifications should */         
  1833.  /* be mailed to the author for consideration for addition to the    */         
  1834.  /* software and incorporation in subsequent releases.               */         
  1835.  /*                                                                  */         
  1836.  /********************************************************************/         
  1837.                                                                                 
  1838. #pragma  csect(code,  "NN@ALLOC")                                               
  1839. #pragma  csect(static,"NN$ALLOC")                                               
  1840. #include "nn.h"                                                                 
  1841.                                                                                 
  1842. /****** Allocate a data set. *****************************************/         
  1843.                                                                                 
  1844. Bool                                                                            
  1845. NNMalloc(dsname,ddname,type,nitems)                                             
  1846. char                      *dsname;                                              
  1847. char                      *ddname;                                              
  1848. enum data_set_type         type;                                                
  1849. int                        nitems;                                              
  1850. {                                                                               
  1851.  int          i;                                                                
  1852.  int          rc;                                                               
  1853.  char        *cp;                                                               
  1854.  Bool         try_new;                                                          
  1855.  short        primary_allocation   ;                                            
  1856.  short        secondary_allocation ;                                            
  1857.  short        directory_blocks     ;                                            
  1858.  short        dsorg                ;                                            
  1859.  __S99parms   stuff99;   /* The manual has it wrong.  No "struct". */           
  1860.  TEXTUNIT    *tu [17];                                                          
  1861.  TEXTUNIT     tu_dsn;                                                           
  1862.  TEXTUNIT     tu_ddn;                                                           
  1863.  TEXTUNIT     tu_member;                                                        
  1864.  TEXTUNIT     tu_stat;                                                          
  1865.  TEXTUNIT     tu_disp;                                                          
  1866.  TEXTUNIT     tu_perm;                                                          
  1867.  TEXTUNIT     tu_rtddn;                                                         
  1868.  TEXTUNIT     tu_rtorg;                                                         
  1869.  TEXTUNIT     tu_block;                                                         
  1870.  TEXTUNIT     tu_prime;                                                         
  1871.  TEXTUNIT     tu_sec;                                                           
  1872.  TEXTUNIT     tu_dir;                                                           
  1873.  TEXTUNIT     tu_recfm;                                                         
  1874.  TEXTUNIT     tu_lrecl;                                                         
  1875.  TEXTUNIT     tu_blksz;                                                         
  1876.  TEXTUNIT     tu_dsorg;                                                         
  1877.  char        *lparp;                                                            
  1878.  char        *rparp;                                                            
  1879.  char         dsnseq [81];                                                      
  1880.  char         member [81];                                                      
  1881.  char         what_to_open[81];                                                 
  1882.  FILE        *mfile;                                                            
  1883.                                                                                 
  1884.                                                                                 
  1885.  try_new = FALSE;                                                               
  1886.                                                                                 
  1887.  memset((char *)&stuff99,0,sizeof(__S99parms));                                 
  1888.                                                                                 
  1889.  strcpy(member,"");                                                             
  1890.  strcpy(dsnseq,dsname);                                                         
  1891.  lparp = strchr(dsnseq,'(');                                                    
  1892.  rparp = strchr(dsnseq,')');                                                    
  1893.  if (lparp && rparp && (lparp < rparp) && (*(rparp+1) == '\0')) {               
  1894.    *lparp = '\0';            /* makes dsnseq the seq part only */               
  1895.    *rparp = '\0';            /* turns member into a string     */               
  1896.    strcpy(member, lparp+1);                                                     
  1897.    type = PDS;                                                                  
  1898.  }                                                                              
  1899.                                                                                 
  1900.  for (;;) {                                                                     
  1901.                                                                                 
  1902.    stuff99.__S99RBLN   = 20;                                                    
  1903.    stuff99.__S99VERB   = S99VRBAL;                                              
  1904.    stuff99.__S99FLAG1  = S99NOCNV << 8;                                         
  1905.    stuff99.__S99ERROR  = 0;                                                     
  1906.    stuff99.__S99INFO   = 0;                                                     
  1907.    stuff99.__S99TXTPP  = tu;                                                    
  1908.    stuff99.__S99FLAG2  = 0;                                                     
  1909.                                                                                 
  1910.    i = 0;                                                                       
  1911.                                                                                 
  1912.    tu[i++] = &tu_dsn;                                                           
  1913.                                                                                 
  1914.    tu_dsn.key        = DALDSNAM;                                                
  1915.    tu_dsn.num        = 1;                                                       
  1916.    tu_dsn.ent.len    = strlen(dsnseq);                                          
  1917.    strcpy(tu_dsn.ent.prm,dsnseq);                                               
  1918.    for (cp=tu_dsn.ent.prm; *cp; cp++) *cp = toupper(*cp);                       
  1919.                                                                                 
  1920.    tu[i++] = &tu_stat;                                                          
  1921.                                                                                 
  1922.    tu_stat.key      = DALSTATS;                                                 
  1923.    tu_stat.num      = 1;                                                        
  1924.    tu_stat.ent.len  = 1;                                                        
  1925.    *tu_stat.ent.prm = (try_new ? NEW : SHR);                                    
  1926.                                                                                 
  1927.    tu[i++] = &tu_disp;                                                          
  1928.                                                                                 
  1929.    tu_disp.key      = DALNDISP;                                                 
  1930.    tu_disp.num      = 1;                                                        
  1931.    tu_disp.ent.len  = 1;                                                        
  1932.    *tu_disp.ent.prm = (try_new ? CATLG : KEEP);                                 
  1933.                                                                                 
  1934.    tu[i++] = &tu_rtorg;                                                         
  1935.                                                                                 
  1936.    tu_rtorg.key     = DALRTORG;                                                 
  1937.    tu_rtorg.num     = 1;                                                        
  1938.    tu_rtorg.ent.len = 2;                                                        
  1939.                                                                                 
  1940.    if (*member) {                                                               
  1941.                                                                                 
  1942.      tu[i++] = &tu_member;                                                      
  1943.                                                                                 
  1944.      tu_member.key     = DALMEMBR;                                              
  1945.      tu_member.num     = 1;                                                     
  1946.      tu_member.ent.len = strlen(member);                                        
  1947.      strcpy(tu_member.ent.prm,member);                                          
  1948.      for (cp=tu_member.ent.prm; *cp; cp++) *cp = toupper(*cp);                  
  1949.                                                                                 
  1950.    }                                                                            
  1951.                                                                                 
  1952.    if (ddname && *ddname) {                                                     
  1953.                                                                                 
  1954.      tu[i++] = &tu_ddn;                                                         
  1955.                                                                                 
  1956.      tu_ddn.key     = DALDDNAM;                                                 
  1957.      tu_ddn.num     = 1;                                                        
  1958.      tu_ddn.ent.len = strlen(ddname);                                           
  1959.      strcpy(tu_ddn.ent.prm,ddname);                                             
  1960.      for (cp=tu_ddn.ent.prm; *cp; cp++) *cp = toupper(*cp);                     
  1961.                                                                                 
  1962.      tu[i++] = &tu_perm;                                                        
  1963.                                                                                 
  1964.      tu_perm.key     = DALPERMA;                                                
  1965.      tu_perm.num     = 0;                                                       
  1966.    }                                                                            
  1967.    else {                                                                       
  1968.                                                                                 
  1969.      tu[i++] = &tu_rtddn;                                                       
  1970.                                                                                 
  1971.      tu_rtddn.key     = DALRTDDN;                                               
  1972.      tu_rtddn.num     = 1;                                                      
  1973.      tu_rtddn.ent.len = 8;                                                      
  1974.      memset(tu_rtddn.ent.prm,' ',8);                                            
  1975.                                                                                 
  1976.    }                                                                            
  1977.                                                                                 
  1978.    if (try_new) {                                                               
  1979.                                                                                 
  1980.      switch (type) {                                                            
  1981.        case PDS:                                                                
  1982.                  primary_allocation   = (short)nitems;                          
  1983.                  secondary_allocation = primary_allocation;                     
  1984.                  directory_blocks     = ((short)nitems/(12*36)+1) * 36;         
  1985.                  dsorg                = DSORG_PO;                               
  1986.                  break;                                                         
  1987.        case SEQ:                                                                
  1988.        default:                                                                 
  1989.                  primary_allocation   = (short)nitems;                          
  1990.                  secondary_allocation = primary_allocation;                     
  1991.                  directory_blocks     = 0;                                      
  1992.                  dsorg                = DSORG_PS;                               
  1993.                  break;                                                         
  1994.      }                                                                          
  1995.                                                                                 
  1996.      tu[i++] = &tu_block;                                                       
  1997.                                                                                 
  1998.      tu_block.key     = DALBLKLN;                                               
  1999.      tu_block.num     = 1;                                                      
  2000.      tu_block.ent.len = 3;                                                      
  2001.      memset(tu_block.ent.prm,0,3);                                              
  2002.      *(short *)(tu_block.ent.prm+1) = 6233;                                     
  2003.                                                                                 
  2004.      tu[i++] = &tu_prime;                                                       
  2005.                                                                                 
  2006.      tu_prime.key     = DALPRIME;                                               
  2007.      tu_prime.num     = 1;                                                      
  2008.      tu_prime.ent.len = 3;                                                      
  2009.      memset(tu_prime.ent.prm,0,3);                                              
  2010.      *(short *)(tu_prime.ent.prm+1) = primary_allocation;                       
  2011.                                                                                 
  2012.      tu[i++] = &tu_sec;                                                         
  2013.                                                                                 
  2014.      tu_sec.key     = DALSECND;                                                 
  2015.      tu_sec.num     = 1;                                                        
  2016.      tu_sec.ent.len = 3;                                                        
  2017.      memset(tu_sec.ent.prm,0,3);                                                
  2018.      *(short *)(tu_sec.ent.prm+1) = secondary_allocation;                       
  2019.                                                                                 
  2020.      tu[i++] = &tu_dir;                                                         
  2021.                                                                                 
  2022.      tu_dir.key     = DALDIR;                                                   
  2023.      tu_dir.num     = 1;                                                        
  2024.      tu_dir.ent.len = 3;                                                        
  2025.      memset(tu_dir.ent.prm,0,3);                                                
  2026.      *(short *)(tu_dir.ent.prm+1) = directory_blocks;                           
  2027.                                                                                 
  2028.      tu[i++] = &tu_recfm;                                                       
  2029.                                                                                 
  2030.      tu_recfm.key        = DALRECFM;                                            
  2031.      tu_recfm.num        = 1;                                                   
  2032.      tu_recfm.ent.len    = 1;                                                   
  2033.      *tu_recfm.ent.prm   = RECFM_VB;                                            
  2034.                                                                                 
  2035.      tu[i++] = &tu_lrecl;                                                       
  2036.                                                                                 
  2037.      tu_lrecl.key        = DALLRECL;                                            
  2038.      tu_lrecl.num        = 1;                                                   
  2039.      tu_lrecl.ent.len    = 2;                                                   
  2040.      *(short *)tu_lrecl.ent.prm   = 259;                                        
  2041.                                                                                 
  2042.      tu[i++] = &tu_blksz;                                                       
  2043.                                                                                 
  2044.      tu_blksz.key        = DALBLKSZ;                                            
  2045.      tu_blksz.num        = 1;                                                   
  2046.      tu_blksz.ent.len    = 2;                                                   
  2047.      *(short *)tu_blksz.ent.prm   = 6233;                                       
  2048.                                                                                 
  2049.      tu[i++] = &tu_dsorg;                                                       
  2050.                                                                                 
  2051.      tu_dsorg.key        = DALDSORG;                                            
  2052.      tu_dsorg.num        = 1;                                                   
  2053.      tu_dsorg.ent.len    = 2;                                                   
  2054.      *(short *)tu_dsorg.ent.prm   = dsorg;                                      
  2055.                                                                                 
  2056.    }                                                                            
  2057.                                                                                 
  2058.    tu[i] = (void *)0x80000000;                                                  
  2059.                                                                                 
  2060.    rc = svc99(&stuff99);                                                        
  2061.                                                                                 
  2062.    if (rc == 0) {                                                               
  2063.      if (!(ddname && *ddname)) {                                                
  2064.        memcpy(ddname,(char *)tu_rtddn.ent.prm,8);                               
  2065.        *(ddname+8) = ' ';                                                       
  2066.        *(strchr(ddname,' ')) = '\0';                                            
  2067.      }                                                                          
  2068.      if (type == SEQ &&                                                         
  2069.          tu_rtorg.ent.prm[0] != 0x40) {                                         
  2070.        fprintf(stderr,"%s: not a sequential data set\n",dsname);                
  2071.        return FALSE;                                                            
  2072.      }                                                                          
  2073.      if (type == PDS &&                                                         
  2074.          tu_rtorg.ent.prm[0] != 0x02) {                                         
  2075.        fprintf(stderr,"%s: not a partitioned data set\n",dsname);               
  2076.        return FALSE;                                                            
  2077.      }                                                                          
  2078.      return TRUE;                                                               
  2079.    }                                                                            
  2080.    else if (!try_new && nitems != 0 && stuff99.__S99ERROR == 0x1708) {          
  2081.     try_new = TRUE;                                                             
  2082.     continue;                                                                   
  2083.    }                                                                            
  2084.    else {                                                                       
  2085.      NNMdfail(rc,&stuff99);                                                     
  2086.      return FALSE;                                                              
  2087.    }                                                                            
  2088.  }                                                                              
  2089. }                                                                               
  2090.                                                                                 
  2091. ./   ADD NAME=NNMAUTH,SSI=01130025                                              
  2092.                                                                                 
  2093.  /********************************************************************/         
  2094.  /*                                                                  */         
  2095.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  2096.  /*                                                                  */         
  2097.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  2098.  /* including the implied warranties of merchantability and fitness, */         
  2099.  /* are expressly denied.                                            */         
  2100.  /*                                                                  */         
  2101.  /* Provided this copyright notice is included, this software may    */         
  2102.  /* be freely distributed and not offered for sale.                  */         
  2103.  /*                                                                  */         
  2104.  /* Changes or modifications may be made and used only by the maker  */         
  2105.  /* of same, and not further distributed.  Such modifications should */         
  2106.  /* be mailed to the author for consideration for addition to the    */         
  2107.  /* software and incorporation in subsequent releases.               */         
  2108.  /*                                                                  */         
  2109.  /********************************************************************/         
  2110.                                                                                 
  2111. #pragma  csect(code,  "NN@AUTH ")                                               
  2112. #pragma  csect(static,"NN$AUTH ")                                               
  2113. #include "nn.h"                                                                 
  2114.                                                                                 
  2115. /****** Send authorization to news server. ***************************/         
  2116.                                                                                 
  2117. Bool                                                                            
  2118. NNMauth(np)                                                                     
  2119. Rstruc nncb *np;                                                                
  2120. {                                                                               
  2121.  char              *lp;                                                         
  2122.  char              *cp;                                                         
  2123.  FILE              *fp;                                                         
  2124.  int                display_rc;                                                 
  2125.  Bool               auth_error;                                                 
  2126.  Bool               connection_probably_closed;                                 
  2127.  char               authdd    [12];                                             
  2128.  char               authline [260];                                             
  2129.  char               host      [65];                                             
  2130.  char               user      [65];                                             
  2131.  char               pass      [65];                                             
  2132.                                                                                 
  2133. #ifdef AUTHFILE                                                                 
  2134.                                                                                 
  2135.  /* Send authorization.                                                         
  2136.   *                                                                             
  2137.   * *** I don't think I have the right numbers yet.  Prepare to                 
  2138.   * *** change them when I get the right ones!                                  
  2139.   * Must be the following as defined in C News source:                          
  2140.   *                                                                             
  2141.   * OK_AUTHSYS    280  authorization system OK                                  
  2142.   * OK_AUTH       281  authorization OK                                         
  2143.   * NEED_AUTHINFO 380  authorization is required                                
  2144.   * NEED_AUTHDATA 381  <type> authorization data required (e.g. PASS)           
  2145.   * ERR_NOAUTH    480  authorization required for command                       
  2146.   * ERR_AUTHSYS   481  authorization system invalid                             
  2147.   * ERR_AUTHREJ   482  authorization data rejected                              
  2148.   * ERR_CMDSYN    501  command syntax error                                     
  2149.   * ERR_COMMAND   500  command not implemented                                  
  2150.   * ERR_ACCESS    502  access to server denied                                  
  2151.   * ERR_AUTHBAD   580  authorization failed                                     
  2152.   *                                                                             
  2153.   * Me:     AUTHINFO USER username                                              
  2154.   * Server: 381 PASS required                                                   
  2155.   *     or: 482 Authorization already completed                                 
  2156.   *     or: 500 Command not recognized                                          
  2157.   *                                                                             
  2158.   * If 482, server does not accept our attempt to gain authorization.           
  2159.   *                                                                             
  2160.   * If 500, authorization is not needed or the server has never                 
  2161.   * heard of authorization.  Either way, we proceed as "authorized".            
  2162.   *                                                                             
  2163.   * If 381 ...                                                                  
  2164.   *                                                                             
  2165.   * Me:     AUTHINFO PASS password                                              
  2166.   * Server: 281 Authorization OK                                                
  2167.   *     or: 482 authorization data rejected                                     
  2168.   *     or: 502 access to served denied                                         
  2169.   *     or: 580 authorization failed                                            
  2170.   *                                                                             
  2171.   * If 502, the server has disconnected me and I should return FALSE.           
  2172.   * Otherwise, everything is OK, and I should return TRUE.                      
  2173.   *                                                                             
  2174.   */                                                                            
  2175.                                                                                 
  2176.  lp = "None - local system error accessing authorization file";                 
  2177.                                                                                 
  2178.  auth_error = FALSE;                                                            
  2179.  connection_probably_closed = FALSE;                                            
  2180.  *host   = '\0';                                                                
  2181.  *user   = '\0';                                                                
  2182.  *pass   = '\0';                                                                
  2183.                                                                                 
  2184.  /* Read user and pass from auth file */                                        
  2185.                                                                                 
  2186.  strcpy(authdd,"dd:");                                                          
  2187.                                                                                 
  2188.  if (!NNMalloc(AUTHFILE,authdd+3,SEQ,0)) {  /* allocate as SHR */               
  2189.    auth_error = TRUE;                                                           
  2190.  }                                                                              
  2191.  else {                                                                         
  2192.    if (!(fp=fopen(authdd,"r"))) {                                               
  2193.      perror(AUTHFILE);                                                          
  2194.      auth_error = TRUE;                                                         
  2195.    }                                                                            
  2196.    else {                                                                       
  2197.      for (;;) {                                                                 
  2198.        fgets(authline,sizeof(authline),fp);                                     
  2199.        if (feof(fp)) break;                                                     
  2200.        if (ferror(fp)) {                                                        
  2201.          fprintf(stderr,"Error reading %s\n",AUTHFILE);                         
  2202.          auth_error = TRUE;                                                     
  2203.          break;                                                                 
  2204.        }                                                                        
  2205.        if (authline[0] == '#') continue;      /* ignore comments */             
  2206.        *host = '\0';                                                            
  2207.        *user = '\0';                                                            
  2208.        *pass = '\0';                                                            
  2209.        sscanf(authline,"%s %s %s", host,user,pass);                             
  2210.        for (cp = host; *cp; cp++) *cp = toupper(*cp);                           
  2211.        if (EQUAL(host,np->nnserver)) break;                                     
  2212.      };                                                                         
  2213.      fclose(fp);                                                                
  2214.    }                                                                            
  2215.    (void)NNMunalc(authdd+3);                                                    
  2216.  }                                                                              
  2217.                                                                                 
  2218.  if (!auth_error) {                                                             
  2219.    if (*user == '\0') return TRUE;  /* Don't do auth if no username */          
  2220.    sprintf(np->nntp_command,"AUTHINFO USER %s", user);                          
  2221.    if (!NNMsockt(np)) return FALSE; /* Send socket command to server */         
  2222.    if (!NNMgsrvl(np,&lp)) return FALSE;  /* Get server line */                  
  2223.    switch (np->nntp_message_num) {                                              
  2224.      case 381: /* PASS required */                                              
  2225.                break;                                                           
  2226.      case 500: /* Command not recognized */                                     
  2227.                /* server does not support AUTHINFO - all clients OK */          
  2228.                return TRUE;                                                     
  2229.      default:  NNMrperr(np);       /* Report protocol error */                  
  2230.                auth_error = TRUE;                                               
  2231.                break;                                                           
  2232.    }                                                                            
  2233.  }                                                                              
  2234.                                                                                 
  2235.  if (!auth_error) {                                                             
  2236.    sprintf(np->nntp_command,"AUTHINFO PASS %s", pass);                          
  2237.    if (!NNMsockt(np)) return FALSE; /* Send socket command to server */         
  2238.    if (!NNMgsrvl(np,&lp)) return FALSE;  /* Get server line */                  
  2239.    switch (np->nntp_message_num) {                                              
  2240.      case 281: /* authorization OK */                                           
  2241.                return TRUE;                                                     
  2242.      case 502: /* access to server denied */                                    
  2243.                /* Also, we have been disconnected at this point. */             
  2244.                connection_probably_closed = TRUE;                               
  2245.                auth_error = TRUE;                                               
  2246.                break;                                                           
  2247.      default:  NNMrperr(np);       /* Report protocol error */                  
  2248.                auth_error = TRUE;                                               
  2249.                break;                                                           
  2250.    }                                                                            
  2251.  }                                                                              
  2252.                                                                                 
  2253.  NNMesrvr(np);                   /* End server read */                          
  2254.                                                                                 
  2255.  if (auth_error) {                                                              
  2256.                                                                                 
  2257.    if (connection_probably_closed) {                                            
  2258.      ERR2("Authorization failed;\                                               
  2259. The NNTP server at %s refuses to authorize you.  \                              
  2260. Some news operations may fail.",\                                               
  2261.           np->nnserver);                                                        
  2262.      np->connection_broken = TRUE;                                              
  2263.      NNMdisc(np);                  /* Complete disconnection */                 
  2264.      return FALSE;                                                              
  2265.    }                                                                            
  2266.    else {                                                                       
  2267.      if (np->batch_mode) {                                                      
  2268.        fprintf(stderr,                                                          
  2269.         "NNMVS could not obtain authorization from the NNTP server.\n");        
  2270.        fprintf(stderr,                                                          
  2271.         "NNMVS will proceed, but some news operations may fail.\n");            
  2272.        fprintf(stderr,                                                          
  2273.         "The response from server %s was:\n\n%s\n\n", np->nnserver,lp);         
  2274.        return TRUE;                                                             
  2275.      }                                                                          
  2276.      else {                                                                     
  2277.        NNMivput(np,"NNSERVER ",np->nnserver,-1);                                
  2278.        NNMivput(np,"NNSRVRSP ",lp,          -1);                                
  2279.        (void)NNMispf(np,"ADDPOP ");                                             
  2280.        (void)NNMispf(np,"DISPLAY PANEL(NNMPAUTH)");                             
  2281.        display_rc = np->ispfrc;                                                 
  2282.        (void)NNMispf(np,"REMPOP ");                                             
  2283.        if (display_rc == 0) return TRUE;                                        
  2284.        else {                                                                   
  2285.          NNMdisc(np);                                                           
  2286.          return FALSE;                                                          
  2287.        }                                                                        
  2288.      }                                                                          
  2289.    }                                                                            
  2290.                                                                                 
  2291.  }                                                                              
  2292.                                                                                 
  2293.  else return TRUE;                                                              
  2294.                                                                                 
  2295. #else                                                                           
  2296.                                                                                 
  2297.  return TRUE;  /* no authorization file defined */                              
  2298.                                                                                 
  2299. #endif                                                                          
  2300.                                                                                 
  2301. }                                                                               
  2302.                                                                                 
  2303. ./   ADD NAME=NNMBATCH,SSI=01630057                                             
  2304.                                                                                 
  2305.  /********************************************************************/         
  2306.  /*                                                                  */         
  2307.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  2308.  /*                                                                  */         
  2309.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  2310.  /* including the implied warranties of merchantability and fitness, */         
  2311.  /* are expressly denied.                                            */         
  2312.  /*                                                                  */         
  2313.  /* Provided this copyright notice is included, this software may    */         
  2314.  /* be freely distributed and not offered for sale.                  */         
  2315.  /*                                                                  */         
  2316.  /* Changes or modifications may be made and used only by the maker  */         
  2317.  /* of same, and not further distributed.  Such modifications should */         
  2318.  /* be mailed to the author for consideration for addition to the    */         
  2319.  /* software and incorporation in subsequent releases.               */         
  2320.  /*                                                                  */         
  2321.  /********************************************************************/         
  2322.                                                                                 
  2323. #pragma  csect(code,  "NN@BATCH")                                               
  2324. #pragma  csect(static,"NN$BATCH")                                               
  2325. #include "nn.h"                                                                 
  2326. #include "nnbatch.h"                                                            
  2327.                                                                                 
  2328. /****** Parse command. ***********************************************/         
  2329.                                                                                 
  2330. static void                                                                     
  2331. parse_command(np,bp,proc)                                                       
  2332. Rstruc nncb         *np;                                                        
  2333. Rstruc batch        *bp;                                                        
  2334. CommandParser        proc;                                                      
  2335. {                                                                               
  2336.  Rstruc newscmd     *cmdp = NULL;                                               
  2337.  struct cmdtree     *treep;                                                     
  2338.                                                                                 
  2339.  cmdp = (proc)(np,bp);                                                          
  2340.                                                                                 
  2341.  if (!cmdp) return;                                                             
  2342.                                                                                 
  2343.  /* If a newscmd structure was returned, add it to the cmd tree. */             
  2344.                                                                                 
  2345.  GETMAIN(treep, struct cmdtree, 1, "command tree");                             
  2346.  if (!treep) {                                                                  
  2347.    bp->input_errors++;                                                          
  2348.    return;                                                                      
  2349.  }                                                                              
  2350.                                                                                 
  2351.  treep->next = NULL;                                                            
  2352.  treep->cmd  = cmdp;                                                            
  2353.                                                                                 
  2354.  if (bp->treebottom == NULL) bp->treetop = treep;                               
  2355.  else               bp->treebottom->next = treep;                               
  2356.  bp->treebottom = treep;                                                        
  2357.                                                                                 
  2358.  return;                                                                        
  2359. }                                                                               
  2360.                                                                                 
  2361. /****** Process requests. ********************************************/         
  2362.                                                                                 
  2363. static void                                                                     
  2364. process_requests(np,bp)                                                         
  2365. Rstruc nncb         *np;                                                        
  2366. Rstruc batch        *bp;                                                        
  2367. {                                                                               
  2368.  Rstruc cmdtree     *treep;                                                     
  2369.                                                                                 
  2370.  if (bp->treetop == NULL) {                                                     
  2371.    fprintf(np->batch_outfile, "There is no processing to be done.\n");          
  2372.  }                                                                              
  2373.                                                                                 
  2374.  for (treep = bp->treetop; treep; treep = treep->next) {                        
  2375.    bp->runtime_error = FALSE;                                                   
  2376.    (treep->cmd->proc) (np,bp,treep->cmd);                                       
  2377.    if (ferror(np->batch_outfile)) {                                             
  2378.      fprintf(stderr,"*** Error writing to batch output file ***\n");            
  2379.    }                                                                            
  2380.    SETB("ERROR",bp->runtime_error);                                             
  2381.  }                                                                              
  2382.                                                                                 
  2383.  return;                                                                        
  2384.                                                                                 
  2385. }                                                                               
  2386.                                                                                 
  2387. /****** Flag unmatched END. ******************************************/         
  2388.                                                                                 
  2389. static struct newscmd *                                                         
  2390. flag_unmatched_end(np,bp)                                                       
  2391. Rstruc nncb         *np;                                                        
  2392. Rstruc batch        *bp;                                                        
  2393. {                                                                               
  2394.  NNMbsynt(np,bp,NULL,0,"END without matching DO seen");                         
  2395.                                                                                 
  2396.  return NULL;                                                                   
  2397. }                                                                               
  2398.                                                                                 
  2399. /****** Flag invalid ISPLINK call. ***********************************/         
  2400.                                                                                 
  2401. static int                                                                      
  2402. flag_invalid_isplink_call(service,argument)                                     
  2403. char  *service;                                                                 
  2404. char  *argument;                                                                
  2405. {                                                                               
  2406.  fprintf(stderr,                                                                
  2407.          "*** Attempt to call ISPLINK in batch mode:\n%8.8s %8.8s\n",           
  2408.          service, argument);                                                    
  2409.                                                                                 
  2410.  return 20;                                                                     
  2411. }                                                                               
  2412.                                                                                 
  2413. /****** Flag invalid ISPEXEC call. ***********************************/         
  2414.                                                                                 
  2415. static int                                                                      
  2416. flag_invalid_ispexec_call(lenp,buf)                                             
  2417. int   *lenp;                                                                    
  2418. char  *buf;                                                                     
  2419. {                                                                               
  2420.  fprintf(stderr,"*** Attempt to call ISPEXEC in batch mode:\n%*.*s\n",          
  2421.                 *lenp, *lenp, buf);                                             
  2422.  return 20;                                                                     
  2423. }                                                                               
  2424.                                                                                 
  2425. /****** NNMVS batch mode. ********************************************/         
  2426.                                                                                 
  2427. int                                                                             
  2428. NNMbatch(np)                                                                    
  2429. Rstruc nncb         *np;                                                        
  2430. {                                                                               
  2431.  struct batch       *bp;                                                        
  2432.  char               *timep;                                                     
  2433.  char               *cp;                                                        
  2434.  CommandParser       proc;                                                      
  2435.  time_t              ltime;                                                     
  2436.  struct batch        batch_struct;                                              
  2437.                                                                                 
  2438.  static char         reserved_words [] = {                                      
  2439.  "AND       DECLARE   DEREGISTERDO        ELSE      "                           
  2440.  "END       EQ        EXEC      EXTRACT   FALSE     "                           
  2441.  "FOR       GE        GT        HELP      IF        "                           
  2442.  "IN        LE        LT        MARK      NE        "                           
  2443.  "NNTP      NO        NOT       OFF       ON        "                           
  2444.  "OR        PUT       QUERY     QUIT      REGISTER  "                           
  2445.  "SET       THEN      TO        TRUE      VARS      "                           
  2446.  "WHEN      YES                "                     };                         
  2447.                                                                                 
  2448.  if (!(np->batch_infile && np->batch_outfile)) {                                
  2449.    fprintf(stderr,"NNMVS: Batch operation failed.  Terminated.\n");             
  2450.    return 16;                                                                   
  2451.  }                                                                              
  2452.                                                                                 
  2453. #ifdef FETCH                                                                    
  2454.                                                                                 
  2455.    np->isplink_pointer = (int (*) ())flag_invalid_isplink_call;                 
  2456.    np->ispexec_pointer = (int (*) ())flag_invalid_ispexec_call;                 
  2457.                                                                                 
  2458. #endif                                                                          
  2459.                                                                                 
  2460.  time(<ime);                                                                  
  2461.                                                                                 
  2462.  timep = ctime(<ime);                                                         
  2463.                                                                                 
  2464.  if ((cp=strchr(timep,'\n'))) *cp = '\0';                                       
  2465.                                                                                 
  2466.  fprintf(np->batch_outfile,"NNMVS news client at %s - %s\n\n",                  
  2467.                            np->client_hostname,                                 
  2468.                            timep);                                              
  2469.                                                                                 
  2470.  bp = &batch_struct;                                                            
  2471.                                                                                 
  2472.  np->batch_hook = bp;                                                           
  2473.                                                                                 
  2474.  memset(bp,0,sizeof(struct batch));                                             
  2475.                                                                                 
  2476.  bp->reserved_words = reserved_words;                                           
  2477.                                                                                 
  2478.  bp->mode        = INITIAL_MODE;                                                
  2479.  bp->curtok.type = NO_TOKEN;                                                    
  2480.  bp->nextok.type = NO_TOKEN;                                                    
  2481.                                                                                 
  2482.  bp->endproc  = flag_unmatched_end;                                             
  2483.                                                                                 
  2484.  /* Declare built-in variables along with initial values. */                    
  2485.                                                                                 
  2486.  /* globally valid */                                                           
  2487.                                                                                 
  2488. #undef  TRUE                                                                    
  2489. #define TRUE (void *)(1)                                                        
  2490.                                                                                 
  2491.  NNMbdecl(np,bp,"LOCALPATH",    STRING_SYMTYPE, np->client_hostname);           
  2492.  NNMbdecl(np,bp,"DATETIME",     STRING_SYMTYPE, timep      );                   
  2493.  NNMbdecl(np,bp,"SERVER",       STRING_SYMTYPE, ""         );                   
  2494.  NNMbdecl(np,bp,"OUTFILE",      STRING_SYMTYPE, ""         );                   
  2495.  NNMbdecl(np,bp,"SERVERLIST",   FLAG_SYMTYPE,   TRUE       );                   
  2496.  NNMbdecl(np,bp,"AUTOREGISTER", FLAG_SYMTYPE,   FALSE      );                   
  2497.  NNMbdecl(np,bp,"AUTODELETE",   FLAG_SYMTYPE,   TRUE       );                   
  2498.  NNMbdecl(np,bp,"AUTOMARK",     FLAG_SYMTYPE,   TRUE       );                   
  2499.  NNMbdecl(np,bp,"ERROR",        FLAG_SYMTYPE,   FALSE      );                   
  2500.  NNMbdecl(np,bp,"EXACTCASE",    FLAG_SYMTYPE,   FALSE      );                   
  2501.  NNMbdecl(np,bp,"TABEXPAND",    FLAG_SYMTYPE,   TRUE       );                   
  2502.  NNMbdecl(np,bp,"APPEND",       FLAG_SYMTYPE,   TRUE       );                   
  2503.  NNMbdecl(np,bp,"SEPARATOR",    STRING_SYMTYPE, ""         );                   
  2504.  NNMbdecl(np,bp,"BLANKSEP",     FLAG_SYMTYPE,   FALSE      );                   
  2505.  NNMbdecl(np,bp,"CHECKPOINT",   FLAG_SYMTYPE,   TRUE       );                   
  2506.                                                                                 
  2507.  /* for newsgroups only */                                                      
  2508.                                                                                 
  2509.  NNMbdecl(np,bp,"GROUP",        STRING_SYMTYPE, ""         );                   
  2510.  NNMbdecl(np,bp,"REGISTERED",   FLAG_SYMTYPE,   FALSE      );                   
  2511.  NNMbdecl(np,bp,"NEWGROUP",     FLAG_SYMTYPE,   FALSE      );                   
  2512.  NNMbdecl(np,bp,"NOSUCHGROUP",  FLAG_SYMTYPE,   FALSE      );                   
  2513.  NNMbdecl(np,bp,"COUNT",        NUMBER_SYMTYPE, 0          );                   
  2514.  NNMbdecl(np,bp,"UNREAD",       NUMBER_SYMTYPE, 0          );                   
  2515.  NNMbdecl(np,bp,"FIRST",        NUMBER_SYMTYPE, 0          );                   
  2516.  NNMbdecl(np,bp,"LAST",         NUMBER_SYMTYPE, 0          );                   
  2517.                                                                                 
  2518.  /* for articles only */                                                        
  2519.                                                                                 
  2520.  NNMbdecl(np,bp,"NUMBER",       NUMBER_SYMTYPE, 0          );                   
  2521.  NNMbdecl(np,bp,"READ",         FLAG_SYMTYPE,   FALSE      );                   
  2522.  NNMbdecl(np,bp,"MISSING",      FLAG_SYMTYPE,   FALSE      );                   
  2523.  NNMbdecl(np,bp,"SUBJECT",      STRING_SYMTYPE, ""         );                   
  2524.  NNMbdecl(np,bp,"DATE",         STRING_SYMTYPE, ""         );                   
  2525.  NNMbdecl(np,bp,"FROM",         STRING_SYMTYPE, ""         );                   
  2526.  NNMbdecl(np,bp,"MESSAGEID",    STRING_SYMTYPE, ""         );                   
  2527.                                                                                 
  2528.  do {                                                                           
  2529.    if ((proc = NNMbgcmd(np,bp))) {                                              
  2530.      parse_command(np,bp,proc);                                                 
  2531.    }                                                                            
  2532.  } while (!bp->eof);                                                            
  2533.                                                                                 
  2534.  if (bp->input_errors > 0) {                                                    
  2535.    fprintf(np->batch_outfile, "\nNo processing due to input errors.\n");        
  2536.    return 12;                                                                   
  2537.  }                                                                              
  2538.                                                                                 
  2539.  else {                                                                         
  2540.                                                                                 
  2541.    fprintf(np->batch_outfile, "\n\nOpening NEWSRC...\n\n");                     
  2542.                                                                                 
  2543.    strcpy(np->newsrc_to_open,"DD:NNNEWSRC");                                    
  2544.                                                                                 
  2545.    NNMonrf(np,NULL);          /* Open NEWSRC file */                            
  2546.                                                                                 
  2547.    fprintf(np->batch_outfile, "\n\nProcessing requests...\n\n");                
  2548.    process_requests(np,bp);                                                     
  2549.                                                                                 
  2550.    fprintf(np->batch_outfile, "\n\nClosing NEWSRC...\n\n");                     
  2551.                                                                                 
  2552.    NNMcnrf(np,NULL,(Fool)TRUE); /* Close  NEWSRC file */                        
  2553.                                                                                 
  2554.  }                                                                              
  2555.                                                                                 
  2556.  /* Clean up any outfile hacking that may have been done. */                    
  2557.                                                                                 
  2558.  SETC("OUTFILE","");                                                            
  2559.  (void)NNMbsout(np,bp);     /* Set output file */                               
  2560.                                                                                 
  2561.  np->batch_hook = NULL;                                                         
  2562.                                                                                 
  2563.  return bp->request_errors;                                                     
  2564.                                                                                 
  2565. }                                                                               
  2566.                                                                                 
  2567. ./   ADD NAME=NNMBBEXP,SSI=01100009                                             
  2568.                                                                                 
  2569.  /********************************************************************/         
  2570.  /*                                                                  */         
  2571.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  2572.  /*                                                                  */         
  2573.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  2574.  /* including the implied warranties of merchantability and fitness, */         
  2575.  /* are expressly denied.                                            */         
  2576.  /*                                                                  */         
  2577.  /* Provided this copyright notice is included, this software may    */         
  2578.  /* be freely distributed and not offered for sale.                  */         
  2579.  /*                                                                  */         
  2580.  /* Changes or modifications may be made and used only by the maker  */         
  2581.  /* of same, and not further distributed.  Such modifications should */         
  2582.  /* be mailed to the author for consideration for addition to the    */         
  2583.  /* software and incorporation in subsequent releases.               */         
  2584.  /*                                                                  */         
  2585.  /********************************************************************/         
  2586.                                                                                 
  2587. #pragma  csect(code,  "NN@BBEXP")                                               
  2588. #pragma  csect(static,"NN$BBEXP")                                               
  2589. #include "nn.h"                                                                 
  2590. #include "nnbatch.h"                                                            
  2591.                                                                                 
  2592. #define CLEAR_THING(X) memset((char *)&X, 0, sizeof(struct thing))              
  2593.                                                                                 
  2594. static void from_exp      ();                                                   
  2595. static void from_choice   ();                                                   
  2596. static void from_relation ();                                                   
  2597. static void from_value    ();                                                   
  2598. static void from_quantity ();                                                   
  2599. static void from_term     ();                                                   
  2600. static void from_factor   ();                                                   
  2601. static void from_unop     ();                                                   
  2602. static void from_addop    ();                                                   
  2603. static void from_mulop    ();                                                   
  2604. static void from_logop    ();                                                   
  2605. static void from_relop    ();                                                   
  2606. static void from_constant ();                                                   
  2607. static void from_variable ();                                                   
  2608. static void from_number   ();                                                   
  2609. static void from_string   ();                                                   
  2610. static void from_flag     ();                                                   
  2611.                                                                                 
  2612. /****** Free old value when replacing it with a new value. ***********/         
  2613.                                                                                 
  2614. #define free_old_value(A,B)  /* */                                              
  2615.                                                                                 
  2616. /* Do nothing yet.  This may not have been a malloc'd value...                  
  2617.  *                                                                              
  2618.  *  static void                                                                 
  2619.  *  free_old_value(np,tp)                                                       
  2620.  *  Rstruc nncb         *np;                                                    
  2621.  *  Rstruc thing        *tp;                                                    
  2622.  *  {                                                                           
  2623.  *                                                                              
  2624.  * if (tp->typ == STRING_SYMTYPE) {                                             
  2625.  * FREEMAIN((char *)tp->val,"old intermediate expression string value");        
  2626.  * tp->val = NULL;                                                              
  2627.  * }                                                                            
  2628.  *                                                                              
  2629.  * return;                                                                      
  2630.  * }                                                                            
  2631.  */                                                                             
  2632.                                                                                 
  2633. /****** Case-insensitive string compare. *****************************/         
  2634.                                                                                 
  2635. static int                                                                      
  2636. Ustrcmp(a,b)                                                                    
  2637. register char  *a;                                                              
  2638. register char  *b;                                                              
  2639. {                                                                               
  2640.  register char  A;                                                              
  2641.  register char  B;                                                              
  2642.                                                                                 
  2643.  while (*a || *b) {                                                             
  2644.    A = toupper(*a++);                                                           
  2645.    B = toupper(*b++);                                                           
  2646.    if (A > B) return 1;                                                         
  2647.    if (A < B) return -1;                                                        
  2648.  }                                                                              
  2649.                                                                                 
  2650.  return 0;                                                                      
  2651. }                                                                               
  2652.                                                                                 
  2653. /****** Case-insensitive string search. ******************************/         
  2654.                                                                                 
  2655. static char *                                                                   
  2656. Ustrstr(b,a)                                                                    
  2657. register char  *b;                                                              
  2658. register char  *a;                                                              
  2659. {                                                                               
  2660.  register char *aa;                                                             
  2661.  register char *bb;                                                             
  2662.                                                                                 
  2663.  if (!*a) return strchr(b,'\0');                                                
  2664.                                                                                 
  2665.  for (;;) {                                                                     
  2666.                                                                                 
  2667.    while (*b && toupper(*a) != toupper(*b)) b++;                                
  2668.                                                                                 
  2669.    if (!*b) return NULL;                                                        
  2670.                                                                                 
  2671.    aa = a;                                                                      
  2672.    bb = b;                                                                      
  2673.    while (*aa && *bb && toupper(*aa) == toupper(*bb)) {                         
  2674.      aa++;                                                                      
  2675.      bb++;                                                                      
  2676.    }                                                                            
  2677.                                                                                 
  2678.    if (!*aa) return a;                                                          
  2679.                                                                                 
  2680.    b++;                                                                         
  2681.  }                                                                              
  2682.                                                                                 
  2683. }                                                                               
  2684.                                                                                 
  2685. /****** Concatenate string values. ***********************************/         
  2686.                                                                                 
  2687. static void                                                                     
  2688. cat(np,bp,tp,tp1,tp2)                                                           
  2689. Rstruc nncb         *np;                                                        
  2690. Rstruc batch        *bp;                                                        
  2691. Rstruc thing        *tp;                                                        
  2692. Rstruc thing        *tp1;                                                       
  2693. Rstruc thing        *tp2;                                                       
  2694. {                                                                               
  2695.  char               *strdata1;                                                  
  2696.  char               *strdata2;                                                  
  2697.  char               *newstr;                                                    
  2698.  int                 newlen;                                                    
  2699.                                                                                 
  2700.  /* for now, just do a lot of getmains and freemains */                         
  2701.                                                                                 
  2702.  free_old_value(np,tp);                                                         
  2703.                                                                                 
  2704.  strdata1 = (char *)tp1->val;                                                   
  2705.  strdata2 = (char *)tp2->val;                                                   
  2706.                                                                                 
  2707.  if (*strdata1 == '\0') {                                                       
  2708.    tp->val = (ANYTYPE)tp2->val;                                                 
  2709.  }                                                                              
  2710.  else if (*strdata2 == '\0') {                                                  
  2711.    tp->val = (ANYTYPE)tp1->val;                                                 
  2712.  }                                                                              
  2713.  else {                                                                         
  2714.                                                                                 
  2715.    newlen = strlen(strdata1) + strlen(strdata2) + 1;                            
  2716.                                                                                 
  2717.    GETMAIN(newstr, 1, newlen, "new concatenated string");                       
  2718.                                                                                 
  2719.    if (!newstr) {                                                               
  2720.      fprintf(np->batch_outfile,                                                 
  2721.       "Error, no storage to concatenate strings: %s, %s\n",                     
  2722.              tp1->val, tp2->val);                                               
  2723.      longjmp(bp->jump,ERROR_GETMAIN_FAILURE);                                   
  2724.    }                                                                            
  2725.                                                                                 
  2726.    strcpy(newstr,(char *)tp1->val);                                             
  2727.    strcat(newstr,(char *)tp2->val);                                             
  2728.                                                                                 
  2729.    tp->val = (ANYTYPE)newstr;                                                   
  2730.                                                                                 
  2731.  }                                                                              
  2732.                                                                                 
  2733.  tp->typ = STRING_SYMTYPE;                                                      
  2734.  free_old_value(np,tp1);                                                        
  2735.  free_old_value(np,tp2);                                                        
  2736.  return;                                                                        
  2737. }                                                                               
  2738.                                                                                 
  2739. /*-------------------------------------------------------------------*/         
  2740.                                                                                 
  2741. static void                                                                     
  2742. convert_to_string(np,bp,tp)                                                     
  2743. Rstruc nncb         *np;                                                        
  2744. Rstruc batch        *bp;                                                        
  2745. Rstruc thing        *tp;                                                        
  2746. {                                                                               
  2747.  Fool                tempflag;                                                  
  2748.  char                tempstr[17];                                               
  2749.                                                                                 
  2750.  switch (tp->typ) {                                                             
  2751.    case STRING_SYMTYPE: return;                                                 
  2752.    case NUMBER_SYMTYPE:                                                         
  2753.                         sprintf(tempstr, "%d", (int)tp->val);                   
  2754.                         tp->val = (ANYTYPE)NNMcopy(np,tempstr);                 
  2755.                         tp->typ = STRING_SYMTYPE;                               
  2756.                         return;                                                 
  2757.    case FLAG_SYMTYPE:                                                           
  2758.                         tempflag = (Fool)tp->val;                               
  2759.                         tp->val = tempflag ? (ANYTYPE)"TRUE"                    
  2760.                                            : (ANYTYPE)"FALSE";                  
  2761.                         tp->typ = STRING_SYMTYPE;                               
  2762.                         return;                                                 
  2763.  }                                                                              
  2764. }                                                                               
  2765.                                                                                 
  2766. /*-------------------------------------------------------------------*/         
  2767.                                                                                 
  2768. static void                                                                     
  2769. convert_to_number(np,bp,tp)                                                     
  2770. Rstruc nncb         *np;                                                        
  2771. Rstruc batch        *bp;                                                        
  2772. Rstruc thing        *tp;                                                        
  2773. {                                                                               
  2774.  Fool                tempflag;                                                  
  2775.                                                                                 
  2776.  switch (tp->typ) {                                                             
  2777.    case NUMBER_SYMTYPE: return;                                                 
  2778.    case FLAG_SYMTYPE:                                                           
  2779.                         tempflag = (Fool)tp->val;                               
  2780.                         tp->val = tempflag ? (ANYTYPE)1                         
  2781.                                            : (ANYTYPE)0;                        
  2782.                         tp->typ = NUMBER_SYMTYPE;                               
  2783.                         return;                                                 
  2784.    case STRING_SYMTYPE:                                                         
  2785.    /* Note: This should be permitted if the string is all numerics,             
  2786.     *       but for now it is always an error.                                  
  2787.     * If permitted, call free_old_value before altering.                        
  2788.     */                                                                          
  2789.                         fprintf(np->batch_outfile,                              
  2790.              "Type mismatch, cannot convert string to number: %s\n",            
  2791.                                 tp->val);                                       
  2792.                         longjmp(bp->jump,ERROR_TYPE_MISMATCH);                  
  2793.  }                                                                              
  2794. }                                                                               
  2795.                                                                                 
  2796. /*-------------------------------------------------------------------*/         
  2797.                                                                                 
  2798. static void                                                                     
  2799. convert_to_flag(np,bp,tp)                                                       
  2800. Rstruc nncb         *np;                                                        
  2801. Rstruc batch        *bp;                                                        
  2802. Rstruc thing        *tp;                                                        
  2803. {                                                                               
  2804.                                                                                 
  2805.  switch (tp->typ) {                                                             
  2806.    case FLAG_SYMTYPE:   return;                                                 
  2807.    case NUMBER_SYMTYPE:                                                         
  2808.    /* Note: This should be permitted if the number is 0 or 1,                   
  2809.     *       but for now it is always an error.                                  
  2810.     */                                                                          
  2811.                         fprintf(np->batch_outfile,                              
  2812.              "Type mismatch, cannot convert number to flag: %d\n",              
  2813.                                 tp->val);                                       
  2814.                         longjmp(bp->jump,ERROR_TYPE_MISMATCH);                  
  2815.    case STRING_SYMTYPE:                                                         
  2816.    /* Note: This should be permitted if the string is "0", "1",                 
  2817.     *       "TRUE", "FALSE", "ON", "OFF", "YES", or "NO",                       
  2818.     *       but for now it is always an error.                                  
  2819.     * If permitted, call free_old_value before altering.                        
  2820.     */                                                                          
  2821.                         fprintf(np->batch_outfile,                              
  2822.              "Type mismatch, cannot convert string to flag: %s\n",              
  2823.                                 tp->val);                                       
  2824.                         longjmp(bp->jump,ERROR_TYPE_MISMATCH);                  
  2825.  }                                                                              
  2826. }                                                                               
  2827.                                                                                 
  2828. /*-------------------------------------------------------------------*/         
  2829.                                                                                 
  2830. static void                                                                     
  2831. from_number(np,bp,tp,p)                                                         
  2832. Rstruc nncb         *np;                                                        
  2833. Rstruc batch        *bp;                                                        
  2834. Rstruc thing        *tp;                                                        
  2835. Number               p;                                                         
  2836. {                                                                               
  2837.                                                                                 
  2838.  tp->val = (ANYTYPE)p->number1;                                                 
  2839.  tp->typ = NUMBER_SYMTYPE;                                                      
  2840.  return;                                                                        
  2841. }                                                                               
  2842.                                                                                 
  2843. /*-------------------------------------------------------------------*/         
  2844.                                                                                 
  2845. static void                                                                     
  2846. from_string(np,bp,tp,p)                                                         
  2847. Rstruc nncb         *np;                                                        
  2848. Rstruc batch        *bp;                                                        
  2849. Rstruc thing        *tp;                                                        
  2850. String               p;                                                         
  2851. {                                                                               
  2852.                                                                                 
  2853.  tp->val = (ANYTYPE)p->string1;                                                 
  2854.  tp->typ = STRING_SYMTYPE;                                                      
  2855.  return;                                                                        
  2856. }                                                                               
  2857.                                                                                 
  2858. /*-------------------------------------------------------------------*/         
  2859.                                                                                 
  2860. static void                                                                     
  2861. from_flag(np,bp,tp,p)                                                           
  2862. Rstruc nncb         *np;                                                        
  2863. Rstruc batch        *bp;                                                        
  2864. Rstruc thing        *tp;                                                        
  2865. Flag                 p;                                                         
  2866. {                                                                               
  2867.                                                                                 
  2868.  tp->val = (ANYTYPE)p->flag1;                                                   
  2869.  tp->typ = FLAG_SYMTYPE;                                                        
  2870.  return;                                                                        
  2871. }                                                                               
  2872.                                                                                 
  2873. /*-------------------------------------------------------------------*/         
  2874.                                                                                 
  2875. static void                                                                     
  2876. from_variable(np,bp,tp,p)                                                       
  2877. Rstruc nncb         *np;                                                        
  2878. Rstruc batch        *bp;                                                        
  2879. Rstruc thing        *tp;                                                        
  2880. Variable             p;                                                         
  2881. {                                                                               
  2882.  enum symtype        type;                                                      
  2883.                                                                                 
  2884.  type = p->s;                                                                   
  2885.                                                                                 
  2886.  tp->val = (ANYTYPE)NNMbvget(np,bp,p->variable1,type);                          
  2887.  tp->typ = type;                                                                
  2888.  return;                                                                        
  2889. }                                                                               
  2890.                                                                                 
  2891. /*-------------------------------------------------------------------*/         
  2892.                                                                                 
  2893. static void                                                                     
  2894. from_constant(np,bp,tp,p)                                                       
  2895. Rstruc nncb         *np;                                                        
  2896. Rstruc batch        *bp;                                                        
  2897. Rstruc thing        *tp;                                                        
  2898. Constant             p;                                                         
  2899. {                                                                               
  2900.                                                                                 
  2901.  switch (p->r) {                                                                
  2902.    case RHSTYPE_A: from_number(np,bp,tp,p->u.a.number1); break;                 
  2903.    case RHSTYPE_B: from_string(np,bp,tp,p->u.b.string1); break;                 
  2904.    case RHSTYPE_C: from_flag  (np,bp,tp,p->u.c.flag1  ); break;                 
  2905.  }                                                                              
  2906.                                                                                 
  2907.  return;                                                                        
  2908. }                                                                               
  2909.                                                                                 
  2910. /*-------------------------------------------------------------------*/         
  2911.                                                                                 
  2912. static void                                                                     
  2913. from_factor(np,bp,tp,p)                                                         
  2914. Rstruc nncb         *np;                                                        
  2915. Rstruc batch        *bp;                                                        
  2916. Rstruc thing        *tp;                                                        
  2917. Factor               p;                                                         
  2918. {                                                                               
  2919.  struct thing        t1;                                                        
  2920.                                                                                 
  2921.  switch (p->r) {                                                                
  2922.    case RHSTYPE_A: from_constant(np,bp,tp,p->u.a.constant1); break;             
  2923.    case RHSTYPE_B: from_variable(np,bp,tp,p->u.b.variable1); break;             
  2924.    case RHSTYPE_C:                                                              
  2925.                    CLEAR_THING(t1);                                             
  2926.                    from_factor(np,bp,&t1,p->u.c.factor2);                       
  2927.                    switch (p->u.c.unop1->op1) {                                 
  2928.                      case ADD_OP:                                               
  2929.                                   convert_to_number(np,bp,&t1);                 
  2930.                                   tp->val = t1.val;                             
  2931.                                   tp->typ = NUMBER_SYMTYPE;                     
  2932.                                   break;                                        
  2933.                      case SUB_OP:                                               
  2934.                                   convert_to_number(np,bp,&t1);                 
  2935.                                   tp->val = (ANYTYPE)                           
  2936.                                             (-((int)t1.val));                   
  2937.                                   tp->typ = NUMBER_SYMTYPE;                     
  2938.                                   break;                                        
  2939.                      case NOT_OP:                                               
  2940.                                   convert_to_flag(np,bp,&t1);                   
  2941.                                   tp->val = (ANYTYPE)                           
  2942.                                             (!((Fool)t1.val));                  
  2943.                                   tp->typ = FLAG_SYMTYPE;                       
  2944.                                   break;                                        
  2945.                    }                                                            
  2946.                    break;                                                       
  2947.    case RHSTYPE_D: from_exp(np,bp,tp,p->u.d.exp1); break;                       
  2948.  }                                                                              
  2949.                                                                                 
  2950.  return;                                                                        
  2951. }                                                                               
  2952.                                                                                 
  2953. /*-------------------------------------------------------------------*/         
  2954.                                                                                 
  2955. static void                                                                     
  2956. from_term(np,bp,tp,p)                                                           
  2957. Rstruc nncb         *np;                                                        
  2958. Rstruc batch        *bp;                                                        
  2959. Rstruc thing        *tp;                                                        
  2960. Term                 p;                                                         
  2961. {                                                                               
  2962.  struct thing        t1;                                                        
  2963.  struct thing        t3;                                                        
  2964.                                                                                 
  2965.  switch (p->r) {                                                                
  2966.    case RHSTYPE_A: from_factor(np,bp,tp,p->u.a.factor1); break;                 
  2967.    case RHSTYPE_B:                                                              
  2968.                    CLEAR_THING(t1);                                             
  2969.                    CLEAR_THING(t3);                                             
  2970.                    from_term  (np,bp,&t1,p->u.b.term1  );                       
  2971.                    from_factor(np,bp,&t3,p->u.b.factor3);                       
  2972.                    convert_to_number(np,bp,&t1);                                
  2973.                    convert_to_number(np,bp,&t3);                                
  2974.                    switch (p->u.b.mulop2->op1) {                                
  2975.                      case MUL_OP:                                               
  2976.                                   /* how to detect overflow? */                 
  2977.                                   tp->val = (ANYTYPE)                           
  2978.                                             ((int)t1.val * (int)t3.val);        
  2979.                                   break;                                        
  2980.                      case DIV_OP:                                               
  2981.                                   if ((int)t3.val == 0) {                       
  2982.                                     fprintf(np->batch_outfile,                  
  2983.                                "Arithmetic error, division by zero\n");         
  2984.                                     longjmp(bp->jump,ERROR_ZERODIVIDE);         
  2985.                                   }                                             
  2986.                                   tp->val = (ANYTYPE)                           
  2987.                                             ((int)t1.val / (int)t3.val);        
  2988.                                   break;                                        
  2989.                    }                                                            
  2990.                    tp->typ = NUMBER_SYMTYPE;                                    
  2991.                    break;                                                       
  2992.  }                                                                              
  2993.                                                                                 
  2994.  return;                                                                        
  2995. }                                                                               
  2996.                                                                                 
  2997. /*-------------------------------------------------------------------*/         
  2998.                                                                                 
  2999. static void                                                                     
  3000. from_quantity(np,bp,tp,p)                                                       
  3001. Rstruc nncb         *np;                                                        
  3002. Rstruc batch        *bp;                                                        
  3003. Rstruc thing        *tp;                                                        
  3004. Quantity             p;                                                         
  3005. {                                                                               
  3006.  struct thing        t1;                                                        
  3007.  struct thing        t3;                                                        
  3008.                                                                                 
  3009.  switch (p->r) {                                                                
  3010.    case RHSTYPE_A: from_term(np,bp,tp,p->u.a.term1); break;                     
  3011.    case RHSTYPE_B:                                                              
  3012.                    CLEAR_THING(t1);                                             
  3013.                    CLEAR_THING(t3);                                             
  3014.                    from_quantity(np,bp,&t1,p->u.b.quantity1);                   
  3015.                    from_term    (np,bp,&t3,p->u.b.term3);                       
  3016.                    convert_to_number(np,bp,&t1);                                
  3017.                    convert_to_number(np,bp,&t3);                                
  3018.                    switch (p->u.b.addop2->op1) {                                
  3019.                      case ADD_OP:                                               
  3020.                                   /* how to detect overflow? */                 
  3021.                                   tp->val = (ANYTYPE)                           
  3022.                                             ((int)t1.val + (int)t3.val);        
  3023.                                   break;                                        
  3024.                      case SUB_OP:                                               
  3025.                                   /* how to detect overflow? */                 
  3026.                                   tp->val = (ANYTYPE)                           
  3027.                                             ((int)t1.val - (int)t3.val);        
  3028.                                   break;                                        
  3029.                    }                                                            
  3030.                    tp->typ = NUMBER_SYMTYPE;                                    
  3031.                    break;                                                       
  3032.  }                                                                              
  3033.                                                                                 
  3034.  return;                                                                        
  3035. }                                                                               
  3036.                                                                                 
  3037. /*-------------------------------------------------------------------*/         
  3038.                                                                                 
  3039. static void                                                                     
  3040. from_value(np,bp,tp,p)                                                          
  3041. Rstruc nncb         *np;                                                        
  3042. Rstruc batch        *bp;                                                        
  3043. Rstruc thing        *tp;                                                        
  3044. Value                p;                                                         
  3045. {                                                                               
  3046.  struct thing        t1;                                                        
  3047.  struct thing        t2;                                                        
  3048.                                                                                 
  3049.  switch (p->r) {                                                                
  3050.    case RHSTYPE_A: from_quantity(np,bp,tp,p->u.a.quantity1); break;             
  3051.    case RHSTYPE_B:                                                              
  3052.                    CLEAR_THING(t1);                                             
  3053.                    CLEAR_THING(t2);                                             
  3054.                    from_value   (np,bp,&t1,p->u.b.value1);                      
  3055.                    from_quantity(np,bp,&t2,p->u.b.quantity2);                   
  3056.                    convert_to_string(np,bp,&t1);                                
  3057.                    convert_to_string(np,bp,&t2);                                
  3058.                    cat(np,bp,tp,&t1,&t2);                                       
  3059.                    break;                                                       
  3060.  }                                                                              
  3061.                                                                                 
  3062.  return;                                                                        
  3063. }                                                                               
  3064.                                                                                 
  3065. /*-------------------------------------------------------------------*/         
  3066.                                                                                 
  3067. static void                                                                     
  3068. from_relation(np,bp,tp,p)                                                       
  3069. Rstruc nncb         *np;                                                        
  3070. Rstruc batch        *bp;                                                        
  3071. Rstruc thing        *tp;                                                        
  3072. Relation             p;                                                         
  3073. {                                                                               
  3074.  enum optype         op;                                                        
  3075.  struct thing        t1;                                                        
  3076.  struct thing        t3;                                                        
  3077.                                                                                 
  3078.  switch (p->r) {                                                                
  3079.    case RHSTYPE_A: from_value(np,bp,tp,p->u.a.value1); break;                   
  3080.    case RHSTYPE_B:                                                              
  3081.         CLEAR_THING(t1);                                                        
  3082.         CLEAR_THING(t3);                                                        
  3083.         from_value(np,bp,&t1,p->u.b.value1);                                    
  3084.         from_value(np,bp,&t3,p->u.b.value3);                                    
  3085.         /* If either value is a string,                                         
  3086.          * or operation is "IN", do string compare.                             
  3087.          * Otherwise do numeric compare.                                        
  3088.          * Note: Currently we are case sensitive.                               
  3089.          *       This possibly should be changed, but                           
  3090.          *       not now...                                                     
  3091.          */                                                                     
  3092.         op = p->u.b.relop2->op1;                                                
  3093.         if (op == IN_OP                                                         
  3094.          || t1.typ == STRING_SYMTYPE                                            
  3095.          || t3.typ == STRING_SYMTYPE) {                                         
  3096.           convert_to_string(np,bp,&t1);                                         
  3097.           convert_to_string(np,bp,&t3);                                         
  3098.           if (bp->exactcase) {                                                  
  3099.             switch (op) {                                                       
  3100.               case EQ_OP: tp->val = (ANYTYPE)                                   
  3101.                           (strcmp((char *)t1.val,(char *)t3.val) == 0);         
  3102.                           break;                                                
  3103.               case NE_OP: tp->val = (ANYTYPE)                                   
  3104.                           (strcmp((char *)t1.val,(char *)t3.val) != 0);         
  3105.                           break;                                                
  3106.               case GT_OP: tp->val = (ANYTYPE)                                   
  3107.                           (strcmp((char *)t1.val,(char *)t3.val) >  0);         
  3108.                           break;                                                
  3109.               case LT_OP: tp->val = (ANYTYPE)                                   
  3110.                           (strcmp((char *)t1.val,(char *)t3.val) <  0);         
  3111.                           break;                                                
  3112.               case GE_OP: tp->val = (ANYTYPE)                                   
  3113.                           (strcmp((char *)t1.val,(char *)t3.val) >= 0);         
  3114.                           break;                                                
  3115.               case LE_OP: tp->val = (ANYTYPE)                                   
  3116.                           (strcmp((char *)t1.val,(char *)t3.val) <= 0);         
  3117.                           break;                                                
  3118.               case IN_OP: tp->val = (ANYTYPE)                                   
  3119.                           (strstr((char *)t3.val,(char *)t1.val)!=NULL);        
  3120.                           break;                                                
  3121.             }                                                                   
  3122.           }                                                                     
  3123.           else {                                                                
  3124.             switch (op) {                                                       
  3125.               case EQ_OP: tp->val = (ANYTYPE)                                   
  3126.                          (Ustrcmp((char *)t1.val,(char *)t3.val) == 0);         
  3127.                           break;                                                
  3128.               case NE_OP: tp->val = (ANYTYPE)                                   
  3129.                          (Ustrcmp((char *)t1.val,(char *)t3.val) != 0);         
  3130.                           break;                                                
  3131.               case GT_OP: tp->val = (ANYTYPE)                                   
  3132.                          (Ustrcmp((char *)t1.val,(char *)t3.val) >  0);         
  3133.                           break;                                                
  3134.               case LT_OP: tp->val = (ANYTYPE)                                   
  3135.                          (Ustrcmp((char *)t1.val,(char *)t3.val) <  0);         
  3136.                           break;                                                
  3137.               case GE_OP: tp->val = (ANYTYPE)                                   
  3138.                          (Ustrcmp((char *)t1.val,(char *)t3.val) >= 0);         
  3139.                           break;                                                
  3140.               case LE_OP: tp->val = (ANYTYPE)                                   
  3141.                          (Ustrcmp((char *)t1.val,(char *)t3.val) <= 0);         
  3142.                           break;                                                
  3143.               case IN_OP: tp->val = (ANYTYPE)                                   
  3144.                          (Ustrstr((char *)t3.val,(char *)t1.val)!=NULL);        
  3145.                           break;                                                
  3146.             }                                                                   
  3147.           }                                                                     
  3148.         }                                                                       
  3149.         else {                                                                  
  3150.           convert_to_number(np,bp,&t1);                                         
  3151.           convert_to_number(np,bp,&t3);                                         
  3152.           switch (op) {                                                         
  3153.             case EQ_OP: tp->val = (ANYTYPE)((int)t1.val == (int)t3.val);        
  3154.                         break;                                                  
  3155.             case NE_OP: tp->val = (ANYTYPE)((int)t1.val != (int)t3.val);        
  3156.                         break;                                                  
  3157.             case GT_OP: tp->val = (ANYTYPE)((int)t1.val >  (int)t3.val);        
  3158.                         break;                                                  
  3159.             case LT_OP: tp->val = (ANYTYPE)((int)t1.val <  (int)t3.val);        
  3160.                         break;                                                  
  3161.             case GE_OP: tp->val = (ANYTYPE)((int)t1.val >= (int)t3.val);        
  3162.                         break;                                                  
  3163.             case LE_OP: tp->val = (ANYTYPE)((int)t1.val <= (int)t3.val);        
  3164.                         break;                                                  
  3165.           }                                                                     
  3166.         }                                                                       
  3167.         tp->typ = FLAG_SYMTYPE;                                                 
  3168.         break;                                                                  
  3169.  }                                                                              
  3170.                                                                                 
  3171.  return;                                                                        
  3172. }                                                                               
  3173.                                                                                 
  3174. /*-------------------------------------------------------------------*/         
  3175.                                                                                 
  3176. static void                                                                     
  3177. from_choice(np,bp,tp,p)                                                         
  3178. Rstruc nncb         *np;                                                        
  3179. Rstruc batch        *bp;                                                        
  3180. Rstruc thing        *tp;                                                        
  3181. Choice               p;                                                         
  3182. {                                                                               
  3183.  struct thing        t1;                                                        
  3184.  struct thing        t3;                                                        
  3185.                                                                                 
  3186.  switch (p->r) {                                                                
  3187.    case RHSTYPE_A: from_relation(np,bp,tp,p->u.a.relation1); break;             
  3188.    case RHSTYPE_B:                                                              
  3189.         CLEAR_THING(t1);                                                        
  3190.         CLEAR_THING(t3);                                                        
  3191.         from_choice  (np,bp,&t1,p->u.b.choice1);                                
  3192.         from_relation(np,bp,&t3,p->u.b.relation3);                              
  3193.         convert_to_flag(np,bp,&t1);                                             
  3194.         convert_to_flag(np,bp,&t3);                                             
  3195.         switch (p->u.b.logop2->op1) {                                           
  3196.           case AND_OP:                                                          
  3197.                        tp->val = (ANYTYPE)                                      
  3198.                                  ((Fool)t1.val && (Fool)t3.val);                
  3199.                        break;                                                   
  3200.           case OR_OP:                                                           
  3201.                        tp->val = (ANYTYPE)                                      
  3202.                                  ((Fool)t1.val || (Fool)t3.val);                
  3203.                        break;                                                   
  3204.         }                                                                       
  3205.         tp->typ = FLAG_SYMTYPE;                                                 
  3206.         break;                                                                  
  3207.  }                                                                              
  3208.                                                                                 
  3209.  return;                                                                        
  3210. }                                                                               
  3211.                                                                                 
  3212. /*-------------------------------------------------------------------*/         
  3213.                                                                                 
  3214. static void                                                                     
  3215. from_exp(np,bp,tp,p)                                                            
  3216. Rstruc nncb         *np;                                                        
  3217. Rstruc batch        *bp;                                                        
  3218. Rstruc thing        *tp;                                                        
  3219. Exp                  p;                                                         
  3220. {                                                                               
  3221.  struct thing        t1;                                                        
  3222.  struct thing        t2;                                                        
  3223.  struct thing        t3;                                                        
  3224.                                                                                 
  3225.  switch (p->r) {                                                                
  3226.    case RHSTYPE_A: from_choice(np,bp,tp,p->u.a.choice1); break;                 
  3227.    case RHSTYPE_B:                                                              
  3228.         CLEAR_THING(t1);                                                        
  3229.         CLEAR_THING(t2);                                                        
  3230.         CLEAR_THING(t3);                                                        
  3231.         from_exp(np,bp,&t1,p->u.b.exp1);                                        
  3232.         from_exp(np,bp,&t2,p->u.b.exp2);                                        
  3233.         from_exp(np,bp,&t3,p->u.b.exp3);                                        
  3234.         convert_to_flag(np,bp,&t1);                                             
  3235.         if ((Fool)t1.val) {                                                     
  3236.           tp->val = t2.val;                                                     
  3237.           tp->typ = t2.typ;                                                     
  3238.         }                                                                       
  3239.         else {                                                                  
  3240.           tp->val = t3.val;                                                     
  3241.           tp->typ = t3.typ;                                                     
  3242.         }                                                                       
  3243.         break;                                                                  
  3244.  }                                                                              
  3245.                                                                                 
  3246.  return;                                                                        
  3247. }                                                                               
  3248.                                                                                 
  3249. /****** Build object from ptree to return as run-time value. *********/         
  3250.                                                                                 
  3251. ANYTYPE                                                                         
  3252. NNMbbexp(np,bp,treep,type)                                                      
  3253. Rstruc nncb         *np;                                                        
  3254. Rstruc batch        *bp;                                                        
  3255. Rstruc ptree        *treep;                                                     
  3256. enum symtype         type;                                                      
  3257. {                                                                               
  3258.  struct thing        it;                                                        
  3259.                                                                                 
  3260.  CLEAR_THING(it);                                                               
  3261.                                                                                 
  3262.  bp->exactcase = GETB("EXACTCASE");                                             
  3263.                                                                                 
  3264.  /* Define return point for run-time errors during evaluation. */               
  3265.                                                                                 
  3266.  if (setjmp(bp->jump) != 0) {                                                   
  3267.    bp->request_errors++;                                                        
  3268.    bp->runtime_error = TRUE;                                                    
  3269.    return NULL;                                                                 
  3270.  }                                                                              
  3271.                                                                                 
  3272.  /* Get the value, whatever type it turns out to be. */                         
  3273.                                                                                 
  3274.  from_exp(np,bp,&it,treep->exp1);                                               
  3275.                                                                                 
  3276.  /* Try to make the value match the requested type. */                          
  3277.                                                                                 
  3278.  switch (type) {                                                                
  3279.                                                                                 
  3280.    case STRING_SYMTYPE: convert_to_string(np,bp,&it); break;                    
  3281.    case NUMBER_SYMTYPE: convert_to_number(np,bp,&it); break;                    
  3282.    case   FLAG_SYMTYPE: convert_to_flag  (np,bp,&it); break;                    
  3283.                                                                                 
  3284.  }                                                                              
  3285.                                                                                 
  3286.  /* Return the value. */                                                        
  3287.                                                                                 
  3288.  return it.val;                                                                 
  3289.                                                                                 
  3290. }                                                                               
  3291.                                                                                 
  3292. ./   ADD NAME=NNMBCONN,SSI=01040031                                             
  3293.                                                                                 
  3294.  /********************************************************************/         
  3295.  /*                                                                  */         
  3296.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3297.  /*                                                                  */         
  3298.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3299.  /* including the implied warranties of merchantability and fitness, */         
  3300.  /* are expressly denied.                                            */         
  3301.  /*                                                                  */         
  3302.  /* Provided this copyright notice is included, this software may    */         
  3303.  /* be freely distributed and not offered for sale.                  */         
  3304.  /*                                                                  */         
  3305.  /* Changes or modifications may be made and used only by the maker  */         
  3306.  /* of same, and not further distributed.  Such modifications should */         
  3307.  /* be mailed to the author for consideration for addition to the    */         
  3308.  /* software and incorporation in subsequent releases.               */         
  3309.  /*                                                                  */         
  3310.  /********************************************************************/         
  3311.                                                                                 
  3312. #pragma  csect(code,  "NN@BCONN")                                               
  3313. #pragma  csect(static,"NN$BCONN")                                               
  3314. #include "nn.h"                                                                 
  3315. #include "nnbatch.h"                                                            
  3316.                                                                                 
  3317. /****** Insure server name. ******************************************/         
  3318.                                                                                 
  3319. static void                                                                     
  3320. insure_server_name(np,bp)                                                       
  3321. Rstruc nncb         *np;                                                        
  3322. Rstruc batch        *bp;                                                        
  3323. {                                                                               
  3324.  char               *servername;                                                
  3325.                                                                                 
  3326.  if (!*np->nnserver) {                                                          
  3327.    servername = GETC("SERVER");                                                 
  3328.    if (servername) {                                                            
  3329.      strncpy(np->nnserver,servername,sizeof(np->nnserver));                     
  3330.    }                                                                            
  3331.  }                                                                              
  3332.                                                                                 
  3333.  return;                                                                        
  3334. }                                                                               
  3335.                                                                                 
  3336. /****** Connect to server in batch mode. *****************************/         
  3337.                                                                                 
  3338. Bool                                                                            
  3339. NNMbconn(np,bp)                                                                 
  3340. Rstruc nncb         *np;                                                        
  3341. Rstruc batch        *bp;                                                        
  3342. {                                                                               
  3343.                                                                                 
  3344.  if (!np->connected_to_server) {                                                
  3345.    insure_server_name(np,bp);                                                   
  3346.    if (!NNMconn(np)) {              /* Connect to server */                     
  3347.      fprintf(np->batch_outfile,"Server connection failed.\n");                  
  3348.    }                                                                            
  3349.  }                                                                              
  3350.                                                                                 
  3351.  return np->connected_to_server;                                                
  3352. }                                                                               
  3353.                                                                                 
  3354. ./   ADD NAME=NNMBDECL,SSI=010A0034                                             
  3355.                                                                                 
  3356.  /********************************************************************/         
  3357.  /*                                                                  */         
  3358.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3359.  /*                                                                  */         
  3360.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3361.  /* including the implied warranties of merchantability and fitness, */         
  3362.  /* are expressly denied.                                            */         
  3363.  /*                                                                  */         
  3364.  /* Provided this copyright notice is included, this software may    */         
  3365.  /* be freely distributed and not offered for sale.                  */         
  3366.  /*                                                                  */         
  3367.  /* Changes or modifications may be made and used only by the maker  */         
  3368.  /* of same, and not further distributed.  Such modifications should */         
  3369.  /* be mailed to the author for consideration for addition to the    */         
  3370.  /* software and incorporation in subsequent releases.               */         
  3371.  /*                                                                  */         
  3372.  /********************************************************************/         
  3373.                                                                                 
  3374. #pragma  csect(code,  "NN@BDECL")                                               
  3375. #pragma  csect(static,"NN$BDECL")                                               
  3376. #include "nn.h"                                                                 
  3377. #include "nnbatch.h"                                                            
  3378.                                                                                 
  3379. /****** Validate a variable name. ************************************/         
  3380.                                                                                 
  3381. static Bool                                                                     
  3382. validate(np,bp,var)                                                             
  3383. Rstruc nncb         *np;                                                        
  3384. Rstruc batch        *bp;                                                        
  3385. char                *var;                                                       
  3386. {                                                                               
  3387.  int                 varlen;                                                    
  3388.  char               *cp;                                                        
  3389.  char                vartest[MAX_RESERVED_WORD_LENGTH];                         
  3390.                                                                                 
  3391.  varlen = strlen(var);                                                          
  3392.  if (varlen < 1 || varlen > MAX_SYMBOL_LENGTH) {                                
  3393.    ERR2(                                                                        
  3394.     "A variable name must be between 1 and %d characters in length.",           
  3395.         MAX_SYMBOL_LENGTH);                                                     
  3396.    return FALSE;                                                                
  3397.  }                                                                              
  3398.                                                                                 
  3399.  if (varlen >= MIN_RESERVED_WORD_LENGTH                                         
  3400.   && varlen <= MAX_RESERVED_WORD_LENGTH) {                                      
  3401.                                                                                 
  3402.    memset(vartest,' ',MAX_RESERVED_WORD_LENGTH);                                
  3403.    memcpy(vartest,var,strlen(var));                                             
  3404.                                                                                 
  3405.    for (cp = bp->reserved_words; *cp != ' '; cp += 10) {                        
  3406.      if (memcmp(vartest,cp,MAX_RESERVED_WORD_LENGTH) == 0) {                    
  3407.        ERR2(                                                                    
  3408.     "The name %s is reserved and cannot be used as a variable name.",           
  3409.             var);                                                               
  3410.        return FALSE;                                                            
  3411.      }                                                                          
  3412.    }                                                                            
  3413.  }                                                                              
  3414.                                                                                 
  3415.  return TRUE;                                                                   
  3416. }                                                                               
  3417.                                                                                 
  3418. /****** Declare a variable symbol. ***********************************/         
  3419.                                                                                 
  3420. struct symtab *                                                                 
  3421. NNMbdecl(np,bp,var,type,val)                                                    
  3422. Rstruc nncb         *np;                                                        
  3423. Rstruc batch        *bp;                                                        
  3424. char                *var;                                                       
  3425. enum symtype         type;                                                      
  3426. ANYTYPE              val;                                                       
  3427. {                                                                               
  3428.  Rstruc symtab      *symp;                                                      
  3429.  Rstruc symtab     **sympref;                                                   
  3430.  struct symtab      *sympnew;                                                   
  3431.  struct symtab      *sympleft;                                                  
  3432.  struct symtab      *sympright;                                                 
  3433.  int                 minimum_value_length;                                      
  3434.  int                 getlen;                                                    
  3435.  int                 comp;                                                      
  3436.  char                vartest[MAX_SYMBOL_LENGTH];                                
  3437.                                                                                 
  3438.  if (!validate(np,bp,var)) {                                                    
  3439.    NNMbsynt(np,bp,var,0,"Variable name cannot be declared");                    
  3440.    return NULL;                                                                 
  3441.  }                                                                              
  3442.  memset(vartest,'\0',MAX_SYMBOL_LENGTH);                                        
  3443.  memcpy(vartest,var,strlen(var));                                               
  3444.                                                                                 
  3445.  switch (type) {                                                                
  3446.    case STRING_SYMTYPE: minimum_value_length = strlen((char *)val) + 1;         
  3447.                         break;                                                  
  3448.    case NUMBER_SYMTYPE: minimum_value_length = 12;                              
  3449.                         break;                                                  
  3450.    case FLAG_SYMTYPE:   minimum_value_length = 6;                               
  3451.                         break;                                                  
  3452.  }                                                                              
  3453.                                                                                 
  3454.  sympleft  = NULL;                                                              
  3455.  sympright = NULL;                                                              
  3456.  sympref   = &bp->symtabp;                                                      
  3457.                                                                                 
  3458.  while ((symp=*sympref)) {                                                      
  3459.    switch ((comp=memcmp(vartest, symp->symvar, MAX_SYMBOL_LENGTH))) {           
  3460.      case 0:   /* equal   */                                                    
  3461.                NNMbsynt(np,bp,var,0,                                            
  3462.                         "Variable being declared already exists");              
  3463.                return NULL;                                                     
  3464.      case 1:   /* greater */                                                    
  3465.                sympref = &symp->right;                                          
  3466.                continue;                                                        
  3467.      default:  /* less    */                                                    
  3468.                sympref = &symp->left;                                           
  3469.                continue;                                                        
  3470.    }                                                                            
  3471.  }                                                                              
  3472.                                                                                 
  3473.  /* Allocate a new symbol table entry for this new symbol and                   
  3474.   * add it to the tree.                                                         
  3475.   */                                                                            
  3476.                                                                                 
  3477.  getlen = offsetof(struct symtab, symval) + minimum_value_length;               
  3478.                                                                                 
  3479.  GETMAIN(sympnew, char, getlen, "new symbol table entry");                      
  3480.  if (!sympnew) {                                                                
  3481.    NNMbsynt(np,bp,var,0,"Not enough storage to declare symbol");                
  3482.    return NULL;                                                                 
  3483.  }                                                                              
  3484.                                                                                 
  3485.  memcpy(sympnew->symvar, vartest, MAX_SYMBOL_LENGTH);                           
  3486.  sympnew->left   = sympleft;                                                    
  3487.  sympnew->right  = sympright;                                                   
  3488.  sympnew->vallen = minimum_value_length;                                        
  3489.  *sympref        = sympnew;                                                     
  3490.                                                                                 
  3491.  sympnew->type = type;                                                          
  3492.                                                                                 
  3493.  switch (type) {                                                                
  3494.    case STRING_SYMTYPE:                                                         
  3495.                         strcpy(sympnew->symval,(char *)val);                    
  3496.                         if (np->debug_file)                                     
  3497.                            fprintf(np->debug_file,                              
  3498.                                    "NNMbdecl: %s set to '%s'\n",                
  3499.                                    sympnew->symvar, sympnew->symval);           
  3500.                         break;                                                  
  3501.    case NUMBER_SYMTYPE:                                                         
  3502.                         sympnew->symnum = (int)val;                             
  3503.                         if (np->debug_file)                                     
  3504.                            fprintf(np->debug_file,                              
  3505.                                    "NNMbdecl: %s set to %d\n",                  
  3506.                                    sympnew->symvar, sympnew->symnum);           
  3507.                         break;                                                  
  3508.    case FLAG_SYMTYPE:                                                           
  3509.                         sympnew->symnum = (int)val ? 1 : 0;                     
  3510.                         if (np->debug_file)                                     
  3511.                            fprintf(np->debug_file,                              
  3512.                                    "NNMbdecl: %s set to %s\n",                  
  3513.                                    sympnew->symvar,                             
  3514.                                    sympnew->symnum ? "TRUE" : "FALSE");         
  3515.                         break;                                                  
  3516.  }                                                                              
  3517.                                                                                 
  3518.                                                                                 
  3519.  return sympnew;                                                                
  3520.                                                                                 
  3521. }                                                                               
  3522.                                                                                 
  3523. ./   ADD NAME=NNMBFLUS,SSI=01060028                                             
  3524.                                                                                 
  3525.  /********************************************************************/         
  3526.  /*                                                                  */         
  3527.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3528.  /*                                                                  */         
  3529.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3530.  /* including the implied warranties of merchantability and fitness, */         
  3531.  /* are expressly denied.                                            */         
  3532.  /*                                                                  */         
  3533.  /* Provided this copyright notice is included, this software may    */         
  3534.  /* be freely distributed and not offered for sale.                  */         
  3535.  /*                                                                  */         
  3536.  /* Changes or modifications may be made and used only by the maker  */         
  3537.  /* of same, and not further distributed.  Such modifications should */         
  3538.  /* be mailed to the author for consideration for addition to the    */         
  3539.  /* software and incorporation in subsequent releases.               */         
  3540.  /*                                                                  */         
  3541.  /********************************************************************/         
  3542.                                                                                 
  3543. #pragma  csect(code,  "NN@BFLUS")                                               
  3544. #pragma  csect(static,"NN$BFLUS")                                               
  3545. #include "nn.h"                                                                 
  3546. #include "nnbatch.h"                                                            
  3547.                                                                                 
  3548. /****** Flush input line. ********************************************/         
  3549.                                                                                 
  3550. void                                                                            
  3551. NNMbflus(np,bp)                                                                 
  3552. Rstruc nncb         *np;                                                        
  3553. Rstruc batch        *bp;                                                        
  3554. {                                                                               
  3555.                                                                                 
  3556.  /* This routine eats tokens, ignoring them, until it sees a                    
  3557.     semicolon or a new line. */                                                 
  3558.                                                                                 
  3559.  if (np->debug_file) {                                                          
  3560.    fprintf(np->debug_file,"Flushing rest of input line.\n");                    
  3561.  }                                                                              
  3562.                                                                                 
  3563.  bp->stop_at_newline = TRUE;                                                    
  3564.                                                                                 
  3565.  for (;;) {                                                                     
  3566.    if (!NNMbgtok(np,bp,TOKEN_FLUSH)) break;  /* get token */                    
  3567.    switch (bp->curtok.type) {                                                   
  3568.      case EOF_TOKEN:                                                            
  3569.      case EOL_TOKEN:                                                            
  3570.      case SEMI_TOKEN:  break;                                                   
  3571.      default:                                                                   
  3572.                        if (np->debug_file) {                                    
  3573.                          fprintf(np->debug_file,"Ignoring token.\n");           
  3574.                        }                                                        
  3575.                        continue;                                                
  3576.    }                                                                            
  3577.    break;                                                                       
  3578.  }                                                                              
  3579.                                                                                 
  3580.  bp->stop_at_newline = FALSE;                                                   
  3581.                                                                                 
  3582.  return;                                                                        
  3583. }                                                                               
  3584.                                                                                 
  3585. ./   ADD NAME=NNMBGCMD,SSI=010F0048                                             
  3586.                                                                                 
  3587.  /********************************************************************/         
  3588.  /*                                                                  */         
  3589.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3590.  /*                                                                  */         
  3591.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3592.  /* including the implied warranties of merchantability and fitness, */         
  3593.  /* are expressly denied.                                            */         
  3594.  /*                                                                  */         
  3595.  /* Provided this copyright notice is included, this software may    */         
  3596.  /* be freely distributed and not offered for sale.                  */         
  3597.  /*                                                                  */         
  3598.  /* Changes or modifications may be made and used only by the maker  */         
  3599.  /* of same, and not further distributed.  Such modifications should */         
  3600.  /* be mailed to the author for consideration for addition to the    */         
  3601.  /* software and incorporation in subsequent releases.               */         
  3602.  /*                                                                  */         
  3603.  /********************************************************************/         
  3604.                                                                                 
  3605. #pragma  csect(code,  "NN@BGCMD")                                               
  3606. #pragma  csect(static,"NN$BGCMD")                                               
  3607. #include "nn.h"                                                                 
  3608. #include "nnbatch.h"                                                            
  3609.                                                                                 
  3610. #define BATCHPARSER(X)   extern struct newscmd * \                              
  3611.                                      X (struct nncb *, struct batch *)          
  3612.                                                                                 
  3613. BATCHPARSER (NNMbphel);       /* Parse batch HELP         command     */        
  3614. BATCHPARSER (NNMbpfor);       /* Parse batch FOR          command     */        
  3615. BATCHPARSER (NNMbpif );       /* Parse batch IF           command     */        
  3616. BATCHPARSER (NNMbpels);       /* Parse batch ELSE         command     */        
  3617. BATCHPARSER (NNMbpque);       /* Parse batch QUERY        command     */        
  3618. BATCHPARSER (NNMbpreg);       /* Parse batch REGISTER     command     */        
  3619. BATCHPARSER (NNMbpder);       /* Parse batch DEREGISTER   command     */        
  3620. BATCHPARSER (NNMbpset);       /* Parse batch SET          command     */        
  3621. BATCHPARSER (NNMbpput);       /* Parse batch PUT          command     */        
  3622. BATCHPARSER (NNMbpexe);       /* Parse batch EXEC         command     */        
  3623. BATCHPARSER (NNMbpqui);       /* Parse batch QUIT         command     */        
  3624. BATCHPARSER (NNMbpnnt);       /* Parse batch NNTP         command     */        
  3625. BATCHPARSER (NNMbplis);       /* Parse batch LIST         command     */        
  3626. BATCHPARSER (NNMbpmar);       /* Parse batch MARK         command     */        
  3627. BATCHPARSER (NNMbpext);       /* Parse batch EXTRACT      command     */        
  3628. BATCHPARSER (NNMbpvar);       /* Parse batch VARS         command     */        
  3629. BATCHPARSER (NNMbpdec);       /* Parse batch DECLARE      command     */        
  3630.                                                                                 
  3631. /****** Get command. *************************************************/         
  3632.                                                                                 
  3633. CommandParser                                                                   
  3634. NNMbgcmd(np,bp)                                                                 
  3635. Rstruc nncb         *np;                                                        
  3636. Rstruc batch        *bp;                                                        
  3637. {                                                                               
  3638.  char               *cp;                                                        
  3639.  struct token       *tp;                                                        
  3640.  CommandParser       cproc;                                                     
  3641.  Bool                command_not_gotten = FALSE;                                
  3642.  Bool                assumed_set        = FALSE;                                
  3643.                                                                                 
  3644.  for (;;) {                                                                     
  3645.                                                                                 
  3646.    bp->stop_at_newline = FALSE;  /* read lines until token found */             
  3647.                                                                                 
  3648.    if (!(tp = PEEK())) {                          /* peek token */              
  3649.       command_not_gotten = TRUE;                                                
  3650.    }                                                                            
  3651.    else switch (tp->type) {                                                     
  3652.      case EOF_TOKEN:                                                            
  3653.             EAT();                                                              
  3654.             return FALSE; /* OK, no more commands to process */                 
  3655.      case WORD_TOKEN:                                                           
  3656.             break;        /* good, what a command should look like */           
  3657.      case EOL_TOKEN:                                                            
  3658.      case SEMI_TOKEN:                                                           
  3659.             EAT();                                                              
  3660.             continue;     /* keep looping */                                    
  3661.      case STRING_TOKEN:                                                         
  3662.             EAT();                                                              
  3663.             NNMbsynt(np,bp,NULL,0,                                              
  3664.                      "Quoted string where command name expected");              
  3665.             command_not_gotten = TRUE;                                          
  3666.             break;                                                              
  3667.      default:                                                                   
  3668.             EAT();                                                              
  3669.             NNMbsynt(np,bp,tp->string,0,                                        
  3670.                      "Invalid token where command name expected");              
  3671.             command_not_gotten = TRUE;                                          
  3672.             break;                                                              
  3673.    }                                                                            
  3674.    break; /* continue only when ';' found */                                    
  3675.  }                                                                              
  3676.                                                                                 
  3677.  /* Determine what the command is.  If the command is not recognized,           
  3678.   * but it is the name of a declared variable, then assume it is SET            
  3679.   * and don't eat the token - let SET see it.                                   
  3680.   */                                                                            
  3681.                                                                                 
  3682.  if (!command_not_gotten) {                                                     
  3683.   cp = tp->string;                                                              
  3684.   if      (EQUAL(cp,"HELP"        )) cproc = NNMbphel;                          
  3685.   else if (EQUAL(cp,"FOR"         )) cproc = NNMbpfor;                          
  3686.   else if (EQUAL(cp,"IF"          )) cproc = NNMbpif ;                          
  3687.   else if (EQUAL(cp,"ELSE"        )) cproc = NNMbpels;                          
  3688.   else if (EQUAL(cp,"QUERY"       )) cproc = NNMbpque;                          
  3689.   else if (EQUAL(cp,"REGISTER"    )) cproc = NNMbpreg;                          
  3690.   else if (EQUAL(cp,"DEREGISTER"  )) cproc = NNMbpder;                          
  3691.   else if (EQUAL(cp,"SET"         )) cproc = NNMbpset;                          
  3692.   else if (EQUAL(cp,"PUT"         )) cproc = NNMbpput;                          
  3693.   else if (EQUAL(cp,"EXEC"        )) cproc = NNMbpexe;                          
  3694.   else if (EQUAL(cp,"QUIT"        )) cproc = NNMbpqui;                          
  3695.   else if (EQUAL(cp,"NNTP"        )) cproc = NNMbpnnt;                          
  3696.   else if (EQUAL(cp,"LIST"        )) cproc = NNMbplis;                          
  3697.   else if (EQUAL(cp,"MARK"        )) cproc = NNMbpmar;                          
  3698.   else if (EQUAL(cp,"EXTRACT"     )) cproc = NNMbpext;                          
  3699.   else if (EQUAL(cp,"VARS"        )) cproc = NNMbpvar;                          
  3700.   else if (EQUAL(cp,"DECLARE"     )) cproc = NNMbpdec;                          
  3701.   else if (EQUAL(cp,"END"         )) cproc = bp->endproc;                       
  3702.                                                                                 
  3703.   else if (NNMbvget(np,bp,cp,NO_SYMTYPE)) { /* if declared var name */          
  3704.     assumed_set = TRUE;                                                         
  3705.     cproc = NNMbpset;                                                           
  3706.   }                                                                             
  3707.   else {                                                                        
  3708.     NNMbsynt(np,bp,cp,0, "Command or variable name unknown");                   
  3709.     command_not_gotten = TRUE;                                                  
  3710.   }                                                                             
  3711.  }                                                                              
  3712.                                                                                 
  3713.  if (!(EQUAL(cp,"ELSE"))) bp->ifcmd = NULL; /*Disallow unmatched ELSE*/         
  3714.                                                                                 
  3715.  if (!assumed_set) EAT();  /* Swallow the command name if 'twas real */         
  3716.                                                                                 
  3717.  if (command_not_gotten) {                                                      
  3718.    fprintf(np->batch_outfile, "Rest of input line ignored.\n");                 
  3719.    NNMbflus(np,bp);       /* Flush rest of tokens on input line */              
  3720.    return FALSE;                                                                
  3721.  }                                                                              
  3722.                                                                                 
  3723.  return cproc;                                                                  
  3724.                                                                                 
  3725. }                                                                               
  3726.                                                                                 
  3727. ./   ADD NAME=NNMBGDO,SSI=01070009                                              
  3728.                                                                                 
  3729.  /********************************************************************/         
  3730.  /*                                                                  */         
  3731.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3732.  /*                                                                  */         
  3733.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3734.  /* including the implied warranties of merchantability and fitness, */         
  3735.  /* are expressly denied.                                            */         
  3736.  /*                                                                  */         
  3737.  /* Provided this copyright notice is included, this software may    */         
  3738.  /* be freely distributed and not offered for sale.                  */         
  3739.  /*                                                                  */         
  3740.  /* Changes or modifications may be made and used only by the maker  */         
  3741.  /* of same, and not further distributed.  Such modifications should */         
  3742.  /* be mailed to the author for consideration for addition to the    */         
  3743.  /* software and incorporation in subsequent releases.               */         
  3744.  /*                                                                  */         
  3745.  /********************************************************************/         
  3746.                                                                                 
  3747. #pragma  csect(code,  "NN@BGDO ")                                               
  3748. #pragma  csect(static,"NN$BGDO ")                                               
  3749. #include "nn.h"                                                                 
  3750. #include "nnbatch.h"                                                            
  3751.                                                                                 
  3752. #define MAGIC_END_COOKIE    (void *)(1)                                         
  3753.                                                                                 
  3754. /****** Handle END command. ******************************************/         
  3755.                                                                                 
  3756. static struct newscmd *                                                         
  3757. handle_end(np,bp)                                                               
  3758. Rstruc nncb         *np;                                                        
  3759. Rstruc batch        *bp;                                                        
  3760. {                                                                               
  3761.                                                                                 
  3762.  NNMbflus(np,bp);  /* flush all tokens following END */                         
  3763.                                                                                 
  3764.  return MAGIC_END_COOKIE;                                                       
  3765. }                                                                               
  3766.                                                                                 
  3767. /****** Get commands, parse them and add to command tree. ************/         
  3768.                                                                                 
  3769. static struct cmdtree *                                                         
  3770. get_multiple_commands(np,bp,mode)                                               
  3771. Rstruc nncb         *np;                                                        
  3772. Rstruc batch        *bp;                                                        
  3773. enum batchmode       mode;                                                      
  3774. {                                                                               
  3775.  Rstruc newscmd     *cmdp        = NULL;                                        
  3776.  struct cmdtree     *treep       = NULL;                                        
  3777.  struct cmdtree     *treetop     = NULL;                                        
  3778.  struct cmdtree     *treebottom  = NULL;                                        
  3779.  CommandParser       proc;                                                      
  3780.  CommandParser       save_endproc;                                              
  3781.  enum batchmode      save_mode;                                                 
  3782.  Bool                bad_command = FALSE;                                       
  3783.  Bool                end_found   = FALSE;                                       
  3784.                                                                                 
  3785.  save_mode    = bp->mode;                                                       
  3786.  bp->mode     = mode;                                                           
  3787.                                                                                 
  3788.  save_endproc = bp->endproc;                                                    
  3789.  bp->endproc  = handle_end;                                                     
  3790.                                                                                 
  3791.  while (!bp->eof) {                                                             
  3792.                                                                                 
  3793.    proc = NNMbgcmd(np,bp);   /* Get next command */                             
  3794.    if (!proc) {              /* If invalid command, continue */                 
  3795.      bad_command = TRUE;                                                        
  3796.      continue;                                                                  
  3797.    }                                                                            
  3798.                                                                                 
  3799.    cmdp = (proc)(np,bp);     /* Parse it returning command tree */              
  3800.    if (!cmdp) {              /* If syntax error, continue */                    
  3801.      bad_command = TRUE;                                                        
  3802.      continue;                                                                  
  3803.    }                                                                            
  3804.                                                                                 
  3805.    if (cmdp == MAGIC_END_COOKIE) {  /* if END seen */                           
  3806.      end_found = TRUE;                                                          
  3807.      break;                                                                     
  3808.    }                                                                            
  3809.                                                                                 
  3810.    /* If a newscmd structure was returned, add it to the cmd tree. */           
  3811.                                                                                 
  3812.    GETMAIN(treep, struct cmdtree, 1, "DO command tree");                        
  3813.    if (!treep) {                                                                
  3814.      bp->input_errors++;                                                        
  3815.      bad_command = TRUE;                                                        
  3816.      continue;                                                                  
  3817.    }                                                                            
  3818.                                                                                 
  3819.    treep->next = NULL;                                                          
  3820.    treep->cmd  = cmdp;                                                          
  3821.                                                                                 
  3822.    if (treebottom == NULL) treetop = treep;                                     
  3823.    else                    treebottom->next = treep;                            
  3824.    treebottom = treep;                                                          
  3825.                                                                                 
  3826.  }                                                                              
  3827.                                                                                 
  3828.  bp->endproc = save_endproc;                                                    
  3829.  bp->mode    = save_mode;                                                       
  3830.                                                                                 
  3831.  if (!end_found) {                                                              
  3832.    NNMbsynt(np,bp,NULL,0,"No END found to match DO");                           
  3833.  }                                                                              
  3834.                                                                                 
  3835.  return treetop;                                                                
  3836. }                                                                               
  3837.                                                                                 
  3838. /****** Get a single command, parse it and make command tree. ********/         
  3839.                                                                                 
  3840. static struct cmdtree *                                                         
  3841. get_single_command(np,bp,mode)                                                  
  3842. Rstruc nncb         *np;                                                        
  3843. Rstruc batch        *bp;                                                        
  3844. enum batchmode       mode;                                                      
  3845. {                                                                               
  3846.  Rstruc newscmd     *cmdp        = NULL;                                        
  3847.  struct cmdtree     *treep       = NULL;                                        
  3848.  struct token       *tp;                                                        
  3849.  CommandParser       proc;                                                      
  3850.  enum batchmode      save_mode;                                                 
  3851.                                                                                 
  3852.  save_mode    = bp->mode;                                                       
  3853.  bp->mode     = mode;                                                           
  3854.                                                                                 
  3855.  if (!(tp = PEEK())) return NULL;                                               
  3856.                                                                                 
  3857.  /* Handle null command (e.g. IF x THEN; ELSE; ) */                             
  3858.                                                                                 
  3859.  if (tp->type == SEMI_TOKEN) return NULL;                                       
  3860.                                                                                 
  3861.  proc = NNMbgcmd(np,bp);   /* Get next command */                               
  3862.  if (!proc) return NULL;   /* If invalid command, error */                      
  3863.                                                                                 
  3864.  cmdp = (proc)(np,bp);     /* Parse it returning command tree */                
  3865.  if (!cmdp) return NULL;   /* If syntax error, error */                         
  3866.                                                                                 
  3867.  bp->mode = save_mode;                                                          
  3868.                                                                                 
  3869.  /* If a newscmd structure was returned, add it to the cmd tree. */             
  3870.                                                                                 
  3871.  GETMAIN(treep, struct cmdtree, 1, "DO command tree");                          
  3872.  if (!treep) {                                                                  
  3873.    bp->input_errors++;                                                          
  3874.    return NULL;                                                                 
  3875.  }                                                                              
  3876.                                                                                 
  3877.  treep->next = NULL;                                                            
  3878.  treep->cmd  = cmdp;                                                            
  3879.                                                                                 
  3880.  return treep;                                                                  
  3881. }                                                                               
  3882.                                                                                 
  3883. /****** Get keyword. *************************************************/         
  3884.                                                                                 
  3885. static Bool                                                                     
  3886. get_keyword(np,bp,key)                                                          
  3887. Rstruc nncb                 *np;                                                
  3888. Rstruc batch                *bp;                                                
  3889. char                        *key;                                               
  3890. {                                                                               
  3891.  struct token               *tp;                                                
  3892.                                                                                 
  3893.  if ((tp = PEEK())                                                              
  3894.   && tp->type == WORD_TOKEN                                                     
  3895.   && EQUAL(tp->string,key)) {                                                   
  3896.    EAT();                                                                       
  3897.    return TRUE;                                                                 
  3898.  }                                                                              
  3899.                                                                                 
  3900.  else return FALSE;                                                             
  3901.                                                                                 
  3902. }                                                                               
  3903.                                                                                 
  3904. /****** Get a DO-END command group. **********************************/         
  3905.                                                                                 
  3906. struct cmdtree *                                                                
  3907. NNMbgdo(np,bp,mode)                                                             
  3908. Rstruc nncb         *np;                                                        
  3909. Rstruc batch        *bp;                                                        
  3910. enum batchmode       mode;                                                      
  3911. {                                                                               
  3912.                                                                                 
  3913.  /* Look for DO (required).  When found, get commands until END seen.*/         
  3914.                                                                                 
  3915.  if (get_keyword(np,bp,"DO")) {                                                 
  3916.    NNMbtras(np,bp,"DO");                                                        
  3917.    return get_multiple_commands(np,bp,mode);                                    
  3918.  }                                                                              
  3919.  else return get_single_command(np,bp,mode);                                    
  3920.                                                                                 
  3921. }                                                                               
  3922.                                                                                 
  3923. ./   ADD NAME=NNMBGEXP,SSI=01340030                                             
  3924.                                                                                 
  3925.  /********************************************************************/         
  3926.  /*                                                                  */         
  3927.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  3928.  /*                                                                  */         
  3929.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  3930.  /* including the implied warranties of merchantability and fitness, */         
  3931.  /* are expressly denied.                                            */         
  3932.  /*                                                                  */         
  3933.  /* Provided this copyright notice is included, this software may    */         
  3934.  /* be freely distributed and not offered for sale.                  */         
  3935.  /*                                                                  */         
  3936.  /* Changes or modifications may be made and used only by the maker  */         
  3937.  /* of same, and not further distributed.  Such modifications should */         
  3938.  /* be mailed to the author for consideration for addition to the    */         
  3939.  /* software and incorporation in subsequent releases.               */         
  3940.  /*                                                                  */         
  3941.  /********************************************************************/         
  3942.                                                                                 
  3943. #pragma  csect(code,  "NN@BGEXP")                                               
  3944. #pragma  csect(static,"NN$BGEXP")                                               
  3945. #include "nn.h"                                                                 
  3946. #include "nnbatch.h"                                                            
  3947.                                                                                 
  3948. static Exp              get_exp();                                              
  3949. static Choice           get_choice();                                           
  3950. static Relation         get_relation();                                         
  3951. static Value            get_value();                                            
  3952. static Quantity         get_quantity();                                         
  3953. static Term             get_term();                                             
  3954. static Factor           get_factor();                                           
  3955. static Unop             get_unop();                                             
  3956. static Addop            get_addop();                                            
  3957. static Mulop            get_mulop();                                            
  3958. static Logop            get_logop();                                            
  3959. static Relop            get_relop();                                            
  3960. static Constant         get_constant();                                         
  3961. static Variable         get_variable();                                         
  3962. static Number           get_number();                                           
  3963. static String           get_string();                                           
  3964. static Flag             get_flag();                                             
  3965.                                                                                 
  3966. static Exp              make_exp();                                             
  3967. static Choice           make_choice();                                          
  3968. static Relation         make_relation();                                        
  3969. static Value            make_value();                                           
  3970. static Quantity         make_quantity();                                        
  3971. static Term             make_term();                                            
  3972. static Factor           make_factor();                                          
  3973. static Unop             make_unop();                                            
  3974. static Addop            make_addop();                                           
  3975. static Mulop            make_mulop();                                           
  3976. static Logop            make_logop();                                           
  3977. static Relop            make_relop();                                           
  3978. static Constant         make_constant();                                        
  3979. static Variable         make_variable();                                        
  3980. static Number           make_number();                                          
  3981. static String           make_string();                                          
  3982. static Flag             make_flag();                                            
  3983.                                                                                 
  3984. /*-------------------------------------------------------------------*/         
  3985.                                                                                 
  3986. static Bool                                                                     
  3987. is_reserved(bp,var)                                                             
  3988. Rstruc batch    *bp;                                                            
  3989. char            *var;                                                           
  3990. {                                                                               
  3991.  char          *cp;                                                             
  3992.  int            varlen = strlen(var);                                           
  3993.  char           vartest[MAX_RESERVED_WORD_LENGTH];                              
  3994.                                                                                 
  3995.  if (varlen >= MIN_RESERVED_WORD_LENGTH                                         
  3996.   && varlen <= MAX_RESERVED_WORD_LENGTH) {                                      
  3997.                                                                                 
  3998.    memset(vartest,' ',MAX_RESERVED_WORD_LENGTH);                                
  3999.    memcpy(vartest,var,varlen);                                                  
  4000.                                                                                 
  4001.    for (cp = bp->reserved_words; *cp != ' '; cp += 10) {                        
  4002.      if (memcmp(vartest,cp,MAX_RESERVED_WORD_LENGTH) == 0) {                    
  4003.        return TRUE;                                                             
  4004.      }                                                                          
  4005.    }                                                                            
  4006.  }                                                                              
  4007.  return FALSE;                                                                  
  4008. }                                                                               
  4009.                                                                                 
  4010. /*-------------------------------------------------------------------*/         
  4011.                                                                                 
  4012. static Flag                                                                     
  4013. make_flag(np,bp,type,v)                                                         
  4014. Rstruc nncb     *np;                                                            
  4015. Rstruc batch    *bp;                                                            
  4016. enum symtype     type;                                                          
  4017. Fool             v;                                                             
  4018. {                                                                               
  4019.  Flag            p;                                                             
  4020.                                                                                 
  4021.  ALLOC(p,flag);                                                                 
  4022.  p->s     = type;                                                               
  4023.  p->flag1 = v;                                                                  
  4024.  return p;                                                                      
  4025.                                                                                 
  4026. }                                                                               
  4027.                                                                                 
  4028. /*-------------------------------------------------------------------*/         
  4029.                                                                                 
  4030. static String                                                                   
  4031. make_string(np,bp,type,v)                                                       
  4032. Rstruc nncb     *np;                                                            
  4033. Rstruc batch    *bp;                                                            
  4034. enum symtype     type;                                                          
  4035. char            *v;                                                             
  4036. {                                                                               
  4037.  String          p;                                                             
  4038.                                                                                 
  4039.  ALLOC(p,string);                                                               
  4040.  p->s       = type;                                                             
  4041.  p->string1 = NNMcopy(np,v);                                                    
  4042.  return p;                                                                      
  4043.                                                                                 
  4044. }                                                                               
  4045.                                                                                 
  4046. /*-------------------------------------------------------------------*/         
  4047.                                                                                 
  4048. static Number                                                                   
  4049. make_number(np,bp,type,v)                                                       
  4050. Rstruc nncb     *np;                                                            
  4051. Rstruc batch    *bp;                                                            
  4052. enum symtype     type;                                                          
  4053. int              v;                                                             
  4054. {                                                                               
  4055.  Number          p;                                                             
  4056.                                                                                 
  4057.  ALLOC(p,number);                                                               
  4058.  p->s       = type;                                                             
  4059.  p->number1 = v;                                                                
  4060.  return p;                                                                      
  4061.                                                                                 
  4062. }                                                                               
  4063.                                                                                 
  4064. /*-------------------------------------------------------------------*/         
  4065.                                                                                 
  4066. static Variable                                                                 
  4067. make_variable(np,bp,type,v)                                                     
  4068. Rstruc nncb     *np;                                                            
  4069. Rstruc batch    *bp;                                                            
  4070. enum symtype     type;                                                          
  4071. char            *v;                                                             
  4072. {                                                                               
  4073.  Variable        p;                                                             
  4074.                                                                                 
  4075.  ALLOC(p,variable);                                                             
  4076.  p->s         = type;                                                           
  4077.  p->variable1 = NNMcopy(np,v);                                                  
  4078.  return p;                                                                      
  4079. }                                                                               
  4080.                                                                                 
  4081. /*-------------------------------------------------------------------*/         
  4082.                                                                                 
  4083. static Relop                                                                    
  4084. make_relop(np,bp,t)                                                             
  4085. Rstruc nncb     *np;                                                            
  4086. Rstruc batch    *bp;                                                            
  4087. enum optype      t;                                                             
  4088. {                                                                               
  4089.  Relop           p;                                                             
  4090.                                                                                 
  4091.  ALLOC(p,relop);                                                                
  4092.  p->op1 = t;                                                                    
  4093.  return p;                                                                      
  4094. }                                                                               
  4095.                                                                                 
  4096. /*-------------------------------------------------------------------*/         
  4097.                                                                                 
  4098. static Logop                                                                    
  4099. make_logop(np,bp,t)                                                             
  4100. Rstruc nncb     *np;                                                            
  4101. Rstruc batch    *bp;                                                            
  4102. enum optype      t;                                                             
  4103. {                                                                               
  4104.  Logop           p;                                                             
  4105.                                                                                 
  4106.  ALLOC(p,logop);                                                                
  4107.  p->op1 = t;                                                                    
  4108.  return p;                                                                      
  4109. }                                                                               
  4110.                                                                                 
  4111. /*-------------------------------------------------------------------*/         
  4112.                                                                                 
  4113. static Mulop                                                                    
  4114. make_mulop(np,bp,t)                                                             
  4115. Rstruc nncb     *np;                                                            
  4116. Rstruc batch    *bp;                                                            
  4117. enum optype      t;                                                             
  4118. {                                                                               
  4119.  Mulop           p;                                                             
  4120.                                                                                 
  4121.  ALLOC(p,mulop);                                                                
  4122.  p->op1 = t;                                                                    
  4123.  return p;                                                                      
  4124. }                                                                               
  4125.                                                                                 
  4126. /*-------------------------------------------------------------------*/         
  4127.                                                                                 
  4128. static Addop                                                                    
  4129. make_addop(np,bp,t)                                                             
  4130. Rstruc nncb     *np;                                                            
  4131. Rstruc batch    *bp;                                                            
  4132. enum optype      t;                                                             
  4133. {                                                                               
  4134.  Addop           p;                                                             
  4135.                                                                                 
  4136.  ALLOC(p,addop);                                                                
  4137.  p->op1 = t;                                                                    
  4138.  return p;                                                                      
  4139. }                                                                               
  4140.                                                                                 
  4141. /*-------------------------------------------------------------------*/         
  4142.                                                                                 
  4143. static Unop                                                                     
  4144. make_unop(np,bp,t)                                                              
  4145. Rstruc nncb     *np;                                                            
  4146. Rstruc batch    *bp;                                                            
  4147. enum optype      t;                                                             
  4148. {                                                                               
  4149.  Unop            p;                                                             
  4150.                                                                                 
  4151.  ALLOC(p,unop);                                                                 
  4152.  p->op1 = t;                                                                    
  4153.  return p;                                                                      
  4154. }                                                                               
  4155.                                                                                 
  4156. /*-------------------------------------------------------------------*/         
  4157.                                                                                 
  4158. static Constant                                                                 
  4159. make_constant_a(np,bp,type,p1)                                                  
  4160. Rstruc nncb     *np;                                                            
  4161. Rstruc batch    *bp;                                                            
  4162. enum symtype     type;                                                          
  4163. Number           p1;                                                            
  4164. {                                                                               
  4165.  Constant        p;                                                             
  4166.                                                                                 
  4167.  ALLOC(p,constant);                                                             
  4168.  p->r           = RHSTYPE_A;                                                    
  4169.  p->s           = type;                                                         
  4170.  p->u.a.number1 = p1;                                                           
  4171.  return p;                                                                      
  4172. }                                                                               
  4173.                                                                                 
  4174. /*-------------------------------------------------------------------*/         
  4175.                                                                                 
  4176. static Constant                                                                 
  4177. make_constant_b(np,bp,type,p1)                                                  
  4178. Rstruc nncb     *np;                                                            
  4179. Rstruc batch    *bp;                                                            
  4180. enum symtype     type;                                                          
  4181. String           p1;                                                            
  4182. {                                                                               
  4183.  Constant        p;                                                             
  4184.                                                                                 
  4185.  ALLOC(p,constant);                                                             
  4186.  p->r           = RHSTYPE_B;                                                    
  4187.  p->s           = type;                                                         
  4188.  p->u.b.string1 = p1;                                                           
  4189.  return p;                                                                      
  4190. }                                                                               
  4191.                                                                                 
  4192. /*-------------------------------------------------------------------*/         
  4193.                                                                                 
  4194. static Constant                                                                 
  4195. make_constant_c(np,bp,type,p1)                                                  
  4196. Rstruc nncb     *np;                                                            
  4197. Rstruc batch    *bp;                                                            
  4198. enum symtype     type;                                                          
  4199. Flag             p1;                                                            
  4200. {                                                                               
  4201.  Constant        p;                                                             
  4202.                                                                                 
  4203.  ALLOC(p,constant);                                                             
  4204.  p->r         = RHSTYPE_C;                                                      
  4205.  p->s         = type;                                                           
  4206.  p->u.c.flag1 = p1;                                                             
  4207.  return p;                                                                      
  4208. }                                                                               
  4209.                                                                                 
  4210. /*-------------------------------------------------------------------*/         
  4211.                                                                                 
  4212. static Factor                                                                   
  4213. make_factor_a(np,bp,type,p1)                                                    
  4214. Rstruc nncb    *np;                                                             
  4215. Rstruc batch    *bp;                                                            
  4216. enum symtype    type;                                                           
  4217. Constant        p1;                                                             
  4218. {                                                                               
  4219.  Factor         p;                                                              
  4220.                                                                                 
  4221.  ALLOC(p,factor);                                                               
  4222.  p->r             = RHSTYPE_A;                                                  
  4223.  p->s             = type;                                                       
  4224.  p->u.a.constant1 = p1;                                                         
  4225.  return p;                                                                      
  4226. }                                                                               
  4227.                                                                                 
  4228. /*-------------------------------------------------------------------*/         
  4229.                                                                                 
  4230. static Factor                                                                   
  4231. make_factor_b(np,bp,type,p1)                                                    
  4232. Rstruc nncb    *np;                                                             
  4233. Rstruc batch    *bp;                                                            
  4234. enum symtype    type;                                                           
  4235. Variable        p1;                                                             
  4236. {                                                                               
  4237.  Factor         p;                                                              
  4238.                                                                                 
  4239.  ALLOC(p,factor);                                                               
  4240.  p->r             = RHSTYPE_B;                                                  
  4241.  p->s             = type;                                                       
  4242.  p->u.b.variable1 = p1;                                                         
  4243.  return p;                                                                      
  4244. }                                                                               
  4245.                                                                                 
  4246. /*-------------------------------------------------------------------*/         
  4247.                                                                                 
  4248. static Factor                                                                   
  4249. make_factor_c(np,bp,type,p1,p2)                                                 
  4250. Rstruc nncb    *np;                                                             
  4251. Rstruc batch    *bp;                                                            
  4252. enum symtype    type;                                                           
  4253. Unop            p1;                                                             
  4254. Factor          p2;                                                             
  4255. {                                                                               
  4256.  Factor         p;                                                              
  4257.                                                                                 
  4258.  ALLOC(p,factor);                                                               
  4259.  p->r             = RHSTYPE_C;                                                  
  4260.  p->s             = type;                                                       
  4261.  p->u.c.unop1     = p1;                                                         
  4262.  p->u.c.factor2   = p2;                                                         
  4263.  return p;                                                                      
  4264. }                                                                               
  4265.                                                                                 
  4266. /*-------------------------------------------------------------------*/         
  4267.                                                                                 
  4268. static Factor                                                                   
  4269. make_factor_d(np,bp,type,p1)                                                    
  4270. Rstruc nncb    *np;                                                             
  4271. Rstruc batch    *bp;                                                            
  4272. enum symtype    type;                                                           
  4273. Exp             p1;                                                             
  4274. {                                                                               
  4275.  Factor         p;                                                              
  4276.                                                                                 
  4277.  ALLOC(p,factor);                                                               
  4278.  p->r        = RHSTYPE_D;                                                       
  4279.  p->s        = type;                                                            
  4280.  p->u.d.exp1 = p1;                                                              
  4281.  return p;                                                                      
  4282. }                                                                               
  4283.                                                                                 
  4284. /*-------------------------------------------------------------------*/         
  4285.                                                                                 
  4286. static Term                                                                     
  4287. make_term_a(np,bp,type,p1)                                                      
  4288. Rstruc nncb    *np;                                                             
  4289. Rstruc batch    *bp;                                                            
  4290. enum symtype    type;                                                           
  4291. Factor          p1;                                                             
  4292. {                                                                               
  4293.  Term           p;                                                              
  4294.                                                                                 
  4295.  ALLOC(p,term);                                                                 
  4296.  p->r           = RHSTYPE_A;                                                    
  4297.  p->s           = type;                                                         
  4298.  p->u.a.factor1 = p1;                                                           
  4299.  return p;                                                                      
  4300. }                                                                               
  4301.                                                                                 
  4302. /*-------------------------------------------------------------------*/         
  4303.                                                                                 
  4304. static Term                                                                     
  4305. make_term_b(np,bp,type,p1,p2,p3)                                                
  4306. Rstruc nncb    *np;                                                             
  4307. Rstruc batch    *bp;                                                            
  4308. enum symtype    type;                                                           
  4309. Term            p1;                                                             
  4310. Mulop           p2;                                                             
  4311. Factor          p3;                                                             
  4312. {                                                                               
  4313.  Term           p;                                                              
  4314.                                                                                 
  4315.  ALLOC(p,term);                                                                 
  4316.  p->r           = RHSTYPE_B;                                                    
  4317.  p->s           = type;                                                         
  4318.  p->u.b.term1   = p1;                                                           
  4319.  p->u.b.mulop2  = p2;                                                           
  4320.  p->u.b.factor3 = p3;                                                           
  4321.  return p;                                                                      
  4322. }                                                                               
  4323.                                                                                 
  4324. /*-------------------------------------------------------------------*/         
  4325.                                                                                 
  4326. static Quantity                                                                 
  4327. make_quantity_a(np,bp,type,p1)                                                  
  4328. Rstruc nncb    *np;                                                             
  4329. Rstruc batch    *bp;                                                            
  4330. enum symtype    type;                                                           
  4331. Term            p1;                                                             
  4332. {                                                                               
  4333.  Quantity       p;                                                              
  4334.                                                                                 
  4335.  ALLOC(p,quantity);                                                             
  4336.  p->r           = RHSTYPE_A;                                                    
  4337.  p->s           = type;                                                         
  4338.  p->u.a.term1   = p1;                                                           
  4339.  return p;                                                                      
  4340. }                                                                               
  4341.                                                                                 
  4342. /*-------------------------------------------------------------------*/         
  4343.                                                                                 
  4344. static Quantity                                                                 
  4345. make_quantity_b(np,bp,type,p1,p2,p3)                                            
  4346. Rstruc nncb    *np;                                                             
  4347. Rstruc batch    *bp;                                                            
  4348. enum symtype    type;                                                           
  4349. Quantity        p1;                                                             
  4350. Addop           p2;                                                             
  4351. Term            p3;                                                             
  4352. {                                                                               
  4353.  Quantity       p;                                                              
  4354.                                                                                 
  4355.  ALLOC(p,quantity);                                                             
  4356.  p->r             = RHSTYPE_B;                                                  
  4357.  p->s             = type;                                                       
  4358.  p->u.b.quantity1 = p1;                                                         
  4359.  p->u.b.addop2    = p2;                                                         
  4360.  p->u.b.term3     = p3;                                                         
  4361.  return p;                                                                      
  4362. }                                                                               
  4363.                                                                                 
  4364. /*-------------------------------------------------------------------*/         
  4365.                                                                                 
  4366. static Value                                                                    
  4367. make_value_a(np,bp,type,p1)                                                     
  4368. Rstruc nncb    *np;                                                             
  4369. Rstruc batch    *bp;                                                            
  4370. enum symtype    type;                                                           
  4371. Quantity        p1;                                                             
  4372. {                                                                               
  4373.  Value           p;                                                             
  4374.                                                                                 
  4375.  ALLOC(p,value);                                                                
  4376.  p->r             = RHSTYPE_A;                                                  
  4377.  p->s             = type;                                                       
  4378.  p->u.a.quantity1 = p1;                                                         
  4379.  return p;                                                                      
  4380. }                                                                               
  4381.                                                                                 
  4382. /*-------------------------------------------------------------------*/         
  4383.                                                                                 
  4384. static Value                                                                    
  4385. make_value_b(np,bp,type,p1,p2)                                                  
  4386. Rstruc nncb    *np;                                                             
  4387. Rstruc batch    *bp;                                                            
  4388. enum symtype    type;                                                           
  4389. Value           p1;                                                             
  4390. Quantity        p2;                                                             
  4391. {                                                                               
  4392.  Value          p;                                                              
  4393.                                                                                 
  4394.  ALLOC(p,value);                                                                
  4395.  p->r             = RHSTYPE_B;                                                  
  4396.  p->s             = type;                                                       
  4397.  p->u.b.value1    = p1;                                                         
  4398.  p->u.b.quantity2 = p2;                                                         
  4399.  return p;                                                                      
  4400. }                                                                               
  4401.                                                                                 
  4402. /*-------------------------------------------------------------------*/         
  4403.                                                                                 
  4404. static Relation                                                                 
  4405. make_relation_a(np,bp,type,p1)                                                  
  4406. Rstruc nncb    *np;                                                             
  4407. Rstruc batch    *bp;                                                            
  4408. enum symtype    type;                                                           
  4409. Value           p1;                                                             
  4410. {                                                                               
  4411.  Relation       p;                                                              
  4412.                                                                                 
  4413.  ALLOC(p,relation);                                                             
  4414.  p->r           = RHSTYPE_A;                                                    
  4415.  p->s           = type;                                                         
  4416.  p->u.a.value1  = p1;                                                           
  4417.  return p;                                                                      
  4418. }                                                                               
  4419.                                                                                 
  4420. /*-------------------------------------------------------------------*/         
  4421.                                                                                 
  4422. static Relation                                                                 
  4423. make_relation_b(np,bp,type,p1,p2,p3)                                            
  4424. Rstruc nncb    *np;                                                             
  4425. Rstruc batch    *bp;                                                            
  4426. enum symtype    type;                                                           
  4427. Value           p1;                                                             
  4428. Relop           p2;                                                             
  4429. Value           p3;                                                             
  4430. {                                                                               
  4431.  Relation       p;                                                              
  4432.                                                                                 
  4433.  ALLOC(p,relation);                                                             
  4434.  p->r             = RHSTYPE_B;                                                  
  4435.  p->s             = type;                                                       
  4436.  p->u.b.value1    = p1;                                                         
  4437.  p->u.b.relop2    = p2;                                                         
  4438.  p->u.b.value3    = p3;                                                         
  4439.  return p;                                                                      
  4440. }                                                                               
  4441.                                                                                 
  4442. /*-------------------------------------------------------------------*/         
  4443.                                                                                 
  4444. static Choice                                                                   
  4445. make_choice_a(np,bp,type,p1)                                                    
  4446. Rstruc nncb    *np;                                                             
  4447. Rstruc batch    *bp;                                                            
  4448. enum symtype    type;                                                           
  4449. Relation        p1;                                                             
  4450. {                                                                               
  4451.  Choice         p;                                                              
  4452.                                                                                 
  4453.  ALLOC(p,choice);                                                               
  4454.  p->r             = RHSTYPE_A;                                                  
  4455.  p->s             = type;                                                       
  4456.  p->u.a.relation1 = p1;                                                         
  4457.  return p;                                                                      
  4458. }                                                                               
  4459.                                                                                 
  4460. /*-------------------------------------------------------------------*/         
  4461.                                                                                 
  4462. static Choice                                                                   
  4463. make_choice_b(np,bp,type,p1,p2,p3)                                              
  4464. Rstruc nncb    *np;                                                             
  4465. Rstruc batch    *bp;                                                            
  4466. enum symtype    type;                                                           
  4467. Choice          p1;                                                             
  4468. Logop           p2;                                                             
  4469. Relation        p3;                                                             
  4470. {                                                                               
  4471.  Choice         p;                                                              
  4472.                                                                                 
  4473.  ALLOC(p,choice);                                                               
  4474.  p->r             = RHSTYPE_B;                                                  
  4475.  p->s             = type;                                                       
  4476.  p->u.b.choice1   = p1;                                                         
  4477.  p->u.b.logop2    = p2;                                                         
  4478.  p->u.b.relation3 = p3;                                                         
  4479.  return p;                                                                      
  4480. }                                                                               
  4481.                                                                                 
  4482. /*-------------------------------------------------------------------*/         
  4483.                                                                                 
  4484. static Exp                                                                      
  4485. make_exp_a(np,bp,type,p1)                                                       
  4486. Rstruc nncb    *np;                                                             
  4487. Rstruc batch    *bp;                                                            
  4488. enum symtype    type;                                                           
  4489. Choice          p1;                                                             
  4490. {                                                                               
  4491.  Exp            p;                                                              
  4492.                                                                                 
  4493.  ALLOC(p,exp);                                                                  
  4494.  p->r           = RHSTYPE_A;                                                    
  4495.  p->s           = type;                                                         
  4496.  p->u.a.choice1 = p1;                                                           
  4497.  return p;                                                                      
  4498. }                                                                               
  4499.                                                                                 
  4500. /*-------------------------------------------------------------------*/         
  4501.                                                                                 
  4502. static Exp                                                                      
  4503. make_exp_b(np,bp,type,p1,p2,p3)                                                 
  4504. Rstruc nncb    *np;                                                             
  4505. Rstruc batch    *bp;                                                            
  4506. enum symtype    type;                                                           
  4507. Exp             p1;                                                             
  4508. Exp             p2;                                                             
  4509. Exp             p3;                                                             
  4510. {                                                                               
  4511.  Exp            p;                                                              
  4512.                                                                                 
  4513.  ALLOC(p,exp);                                                                  
  4514.  p->r        = RHSTYPE_B;                                                       
  4515.  p->s        = type;                                                            
  4516.  p->u.b.exp1 = p1;                                                              
  4517.  p->u.b.exp2 = p2;                                                              
  4518.  p->u.b.exp3 = p3;                                                              
  4519.  return p;                                                                      
  4520. }                                                                               
  4521.                                                                                 
  4522. /*===================================================================*/         
  4523.                                                                                 
  4524. static Flag                                                                     
  4525. get_flag(np,bp)                                                                 
  4526. Rstruc nncb         *np;                                                        
  4527. Rstruc batch        *bp;                                                        
  4528. {                                                                               
  4529.  struct token       *tp;                                                        
  4530.                                                                                 
  4531.  if (!(tp = PEEK())) LOSE;                                                      
  4532.  switch (tp->type) {                                                            
  4533.    case WORD_TOKEN:                                                             
  4534.      if (EQUAL(tp->string,"FALSE") ||                                           
  4535.          EQUAL(tp->string,"NO"   ) ||                                           
  4536.          EQUAL(tp->string,"OFF"  )) {                                           
  4537.        EAT();                                                                   
  4538.        return make_flag(np,bp,FLAG_SYMTYPE,FALSE);                              
  4539.      }                                                                          
  4540.      else                                                                       
  4541.      if (EQUAL(tp->string,"TRUE" ) ||                                           
  4542.          EQUAL(tp->string,"YES"  ) ||                                           
  4543.          EQUAL(tp->string,"ON"   )) {                                           
  4544.        EAT();                                                                   
  4545.        return make_flag(np,bp,FLAG_SYMTYPE,TRUE);                               
  4546.      }                                                                          
  4547.    default:        return NULL;                                                 
  4548.  }                                                                              
  4549. }                                                                               
  4550.                                                                                 
  4551. /*-------------------------------------------------------------------*/         
  4552.                                                                                 
  4553. static String                                                                   
  4554. get_string(np,bp)                                                               
  4555. Rstruc nncb         *np;                                                        
  4556. Rstruc batch        *bp;                                                        
  4557. {                                                                               
  4558.  struct token       *tp;                                                        
  4559.                                                                                 
  4560.  if (!(tp = PEEK())) LOSE;                                                      
  4561.  switch (tp->type) {                                                            
  4562.    case STRING_TOKEN:                                                           
  4563.             EAT();                                                              
  4564.             return make_string(np,bp,STRING_SYMTYPE,tp->string);                
  4565.    default: return NULL;                                                        
  4566.  }                                                                              
  4567. }                                                                               
  4568.                                                                                 
  4569. /*-------------------------------------------------------------------*/         
  4570.                                                                                 
  4571. static Number                                                                   
  4572. get_number(np,bp)                                                               
  4573. Rstruc nncb         *np;                                                        
  4574. Rstruc batch        *bp;                                                        
  4575. {                                                                               
  4576.  struct token       *tp;                                                        
  4577.                                                                                 
  4578.  if (!(tp = PEEK())) LOSE;                                                      
  4579.  switch (tp->type) {                                                            
  4580.    case NUMBER_TOKEN:                                                           
  4581.             EAT();                                                              
  4582.             return make_number(np,bp,NUMBER_SYMTYPE,tp->number);                
  4583.    default: return NULL;                                                        
  4584.  }                                                                              
  4585. }                                                                               
  4586.                                                                                 
  4587. /*-------------------------------------------------------------------*/         
  4588.                                                                                 
  4589. static Variable                                                                 
  4590. get_variable(np,bp)                                                             
  4591. Rstruc nncb         *np;                                                        
  4592. Rstruc batch        *bp;                                                        
  4593. {                                                                               
  4594.  struct token       *tp;                                                        
  4595.  enum symtype        type;                                                      
  4596.                                                                                 
  4597.  if (!(tp = PEEK())) LOSE;                                                      
  4598.  switch (tp->type) {                                                            
  4599.    case WORD_TOKEN:                                                             
  4600.             if (is_reserved(bp,tp->string)) return NULL;                        
  4601.             EAT();                                                              
  4602.             type = (enum symtype)NNMbvget(np,bp,tp->string,NO_SYMTYPE);         
  4603.             if (type == NO_SYMTYPE) ERR("variable not declared");               
  4604.             return make_variable(np,bp,type,tp->string);                        
  4605.    default: return NULL;                                                        
  4606.  }                                                                              
  4607. }                                                                               
  4608.                                                                                 
  4609. /*-------------------------------------------------------------------*/         
  4610.                                                                                 
  4611. static Constant                                                                 
  4612. get_constant(np,bp)                                                             
  4613. Rstruc nncb         *np;                                                        
  4614. Rstruc batch        *bp;                                                        
  4615. {                                                                               
  4616.  Number              a1;                                                        
  4617.  String              b1;                                                        
  4618.  Flag                c1;                                                        
  4619.                                                                                 
  4620.  if ((a1 = get_number(np,bp)))                                                  
  4621.     return make_constant_a(np,bp,NUMBER_SYMTYPE,a1);                            
  4622.  if ((b1 = get_string(np,bp)))                                                  
  4623.     return make_constant_b(np,bp,STRING_SYMTYPE,b1);                            
  4624.  if ((c1 = get_flag(np,bp)))                                                    
  4625.     return make_constant_c(np,bp,FLAG_SYMTYPE,c1);                              
  4626.  return NULL;                                                                   
  4627. }                                                                               
  4628.                                                                                 
  4629. /*-------------------------------------------------------------------*/         
  4630.                                                                                 
  4631. static Addop                                                                    
  4632. get_addop(np,bp)                                                                
  4633. Rstruc nncb         *np;                                                        
  4634. Rstruc batch        *bp;                                                        
  4635. {                                                                               
  4636.  struct token       *tp;                                                        
  4637.                                                                                 
  4638.  if (!(tp = PEEK())) LOSE;                                                      
  4639.  switch (tp->type) {                                                            
  4640.    case PLUS_TOKEN:  EAT(); return make_addop(np,bp,ADD_OP);                    
  4641.    case MINUS_TOKEN: EAT(); return make_addop(np,bp,SUB_OP);                    
  4642.    default:          return NULL;                                               
  4643.  }                                                                              
  4644. }                                                                               
  4645.                                                                                 
  4646. /*-------------------------------------------------------------------*/         
  4647.                                                                                 
  4648. static Mulop                                                                    
  4649. get_mulop(np,bp)                                                                
  4650. Rstruc nncb         *np;                                                        
  4651. Rstruc batch        *bp;                                                        
  4652. {                                                                               
  4653.  struct token       *tp;                                                        
  4654.                                                                                 
  4655.  if (!(tp = PEEK())) LOSE;                                                      
  4656.  switch (tp->type) {                                                            
  4657.    case TIMES_TOKEN:  EAT(); return make_mulop(np,bp,MUL_OP);                   
  4658.    case OVER_TOKEN:   EAT(); return make_mulop(np,bp,DIV_OP);                   
  4659.    default:           return NULL;                                              
  4660.  }                                                                              
  4661. }                                                                               
  4662.                                                                                 
  4663. /*-------------------------------------------------------------------*/         
  4664.                                                                                 
  4665. static Logop                                                                    
  4666. get_logop(np,bp)                                                                
  4667. Rstruc nncb         *np;                                                        
  4668. Rstruc batch        *bp;                                                        
  4669. {                                                                               
  4670.  struct token       *tp;                                                        
  4671.                                                                                 
  4672.  if (!(tp = PEEK())) LOSE;                                                      
  4673.  switch (tp->type) {                                                            
  4674.    case AND_TOKEN:  EAT(); return make_logop(np,bp,AND_OP);                     
  4675.    case OR_TOKEN:   EAT(); return make_logop(np,bp,OR_OP);                      
  4676.    case WORD_TOKEN:                                                             
  4677.      if (EQUAL(tp->string,"AND")) {                                             
  4678.        EAT();                                                                   
  4679.        return make_logop(np,bp,AND_OP);                                         
  4680.      }                                                                          
  4681.      if (EQUAL(tp->string,"OR"))  {                                             
  4682.        EAT();                                                                   
  4683.        return make_logop(np,bp,OR_OP);                                          
  4684.      }                                                                          
  4685.      return NULL;                                                               
  4686.    default:             return NULL;                                            
  4687.  }                                                                              
  4688. }                                                                               
  4689.                                                                                 
  4690. /*-------------------------------------------------------------------*/         
  4691.                                                                                 
  4692. static Relop                                                                    
  4693. get_relop(np,bp)                                                                
  4694. Rstruc nncb         *np;                                                        
  4695. Rstruc batch        *bp;                                                        
  4696. {                                                                               
  4697.  struct token       *tp;                                                        
  4698.                                                                                 
  4699.  if (!(tp = PEEK())) LOSE;                                                      
  4700.  switch (tp->type) {                                                            
  4701.    case EQ_TOKEN:  EAT(); return make_relop(np,bp,EQ_OP);                       
  4702.    case NE_TOKEN:  EAT(); return make_relop(np,bp,NE_OP);                       
  4703.    case GT_TOKEN:  EAT(); return make_relop(np,bp,GT_OP);                       
  4704.    case LT_TOKEN:  EAT(); return make_relop(np,bp,LT_OP);                       
  4705.    case GE_TOKEN:  EAT(); return make_relop(np,bp,GE_OP);                       
  4706.    case LE_TOKEN:  EAT(); return make_relop(np,bp,LE_OP);                       
  4707.    case WORD_TOKEN:                                                             
  4708.      if (EQUAL(tp->string,"IN")) {EAT();                                        
  4709.                                   return make_relop(np,bp,IN_OP);}              
  4710.      if (EQUAL(tp->string,"EQ")) {EAT();                                        
  4711.                                   return make_relop(np,bp,EQ_OP);}              
  4712.      if (EQUAL(tp->string,"NE")) {EAT();                                        
  4713.                                   return make_relop(np,bp,NE_OP);}              
  4714.      if (EQUAL(tp->string,"GT")) {EAT();                                        
  4715.                                   return make_relop(np,bp,GT_OP);}              
  4716.      if (EQUAL(tp->string,"LT")) {EAT();                                        
  4717.                                   return make_relop(np,bp,LT_OP);}              
  4718.      if (EQUAL(tp->string,"GE")) {EAT();                                        
  4719.                                   return make_relop(np,bp,GE_OP);}              
  4720.      if (EQUAL(tp->string,"LE")) {EAT();                                        
  4721.                                   return make_relop(np,bp,LE_OP);}              
  4722.      return NULL;                                                               
  4723.    default:       return NULL;                                                  
  4724.  }                                                                              
  4725. }                                                                               
  4726.                                                                                 
  4727. /*-------------------------------------------------------------------*/         
  4728.                                                                                 
  4729. static Unop                                                                     
  4730. get_unop(np,bp)                                                                 
  4731. Rstruc nncb         *np;                                                        
  4732. Rstruc batch        *bp;                                                        
  4733. {                                                                               
  4734.  struct token       *tp;                                                        
  4735.                                                                                 
  4736.  if (!(tp = PEEK())) LOSE;                                                      
  4737.  switch (tp->type) {                                                            
  4738.    case MINUS_TOKEN: EAT(); return make_unop(np,bp,SUB_OP);                     
  4739.    case PLUS_TOKEN:  EAT(); return make_unop(np,bp,ADD_OP);                     
  4740.    case NOT_TOKEN:   EAT(); return make_unop(np,bp,NOT_OP);                     
  4741.    case WORD_TOKEN:                                                             
  4742.      if (EQUAL(tp->string,"NOT")) {EAT();                                       
  4743.                                    return make_unop(np,bp,NOT_OP);}             
  4744.      return NULL;                                                               
  4745.    default:          return NULL;                                               
  4746.  }                                                                              
  4747. }                                                                               
  4748.                                                                                 
  4749. /*-------------------------------------------------------------------*/         
  4750.                                                                                 
  4751. static Bool                                                                     
  4752. get_word(np,bp,word)                                                            
  4753. Rstruc nncb         *np;                                                        
  4754. Rstruc batch        *bp;                                                        
  4755. char                *word;                                                      
  4756. {                                                                               
  4757.  struct token       *tp;                                                        
  4758.                                                                                 
  4759.  if (!(tp = PEEK())) LOSE;                                                      
  4760.  switch (tp->type) {                                                            
  4761.    case WORD_TOKEN:                                                             
  4762.                     if (EQUAL(tp->string,word)) {EAT(); return TRUE;}           
  4763.                     else return FALSE;                                          
  4764.    default:         return FALSE;                                               
  4765.  }                                                                              
  4766. }                                                                               
  4767.                                                                                 
  4768. /*-------------------------------------------------------------------*/         
  4769.                                                                                 
  4770. static Bool                                                                     
  4771. get_lpar(np,bp)                                                                 
  4772. Rstruc nncb         *np;                                                        
  4773. Rstruc batch        *bp;                                                        
  4774. {                                                                               
  4775.  struct token       *tp;                                                        
  4776.                                                                                 
  4777.  if (!(tp = PEEK())) LOSE;                                                      
  4778.  switch (tp->type) {                                                            
  4779.    case LPAR_TOKEN: EAT(); return TRUE;                                         
  4780.    default: return FALSE;                                                       
  4781.  }                                                                              
  4782. }                                                                               
  4783.                                                                                 
  4784. /*-------------------------------------------------------------------*/         
  4785.                                                                                 
  4786. static Bool                                                                     
  4787. get_rpar(np,bp)                                                                 
  4788. Rstruc nncb         *np;                                                        
  4789. Rstruc batch        *bp;                                                        
  4790. {                                                                               
  4791.  struct token       *tp;                                                        
  4792.                                                                                 
  4793.  if (!(tp = PEEK())) LOSE;                                                      
  4794.  switch (tp->type) {                                                            
  4795.    case RPAR_TOKEN: EAT(); return TRUE;                                         
  4796.    default: return FALSE;                                                       
  4797.  }                                                                              
  4798. }                                                                               
  4799.                                                                                 
  4800. /*-------------------------------------------------------------------*/         
  4801.                                                                                 
  4802. static Factor                                                                   
  4803. get_factor(np,bp)                                                               
  4804. Rstruc nncb     *np;                                                            
  4805. Rstruc batch    *bp;                                                            
  4806. {                                                                               
  4807.  Constant        a1;                                                            
  4808.  Variable        b1;                                                            
  4809.  Unop            c1;                                                            
  4810.  Factor          c2;                                                            
  4811.  Exp             d1;                                                            
  4812.  enum symtype    type;                                                          
  4813.  enum symtype    type2;                                                         
  4814.                                                                                 
  4815.  /* a:  factor -> constant */                                                   
  4816.                                                                                 
  4817.  if (a1 = get_constant(np,bp)) {                                                
  4818.    type = a1->s;                                                                
  4819.    return make_factor_a(np,bp,type,a1);                                         
  4820.  }                                                                              
  4821.                                                                                 
  4822.  /* b:  factor -> variable */                                                   
  4823.                                                                                 
  4824.  if ((b1 = get_variable(np,bp))) {                                              
  4825.    type = b1->s;                                                                
  4826.    return make_factor_b(np,bp,type,b1);                                         
  4827.  }                                                                              
  4828.                                                                                 
  4829.  /* c:  factor -> unop factor */                                                
  4830.                                                                                 
  4831.  if ((c1 = get_unop(np,bp))) {                                                  
  4832.    if (!(c2 = get_factor(np,bp))) ERR("expecting factor");                      
  4833.    type2 = c2->s;                                                               
  4834.    switch (c1->op1) {                                                           
  4835.      case SUB_OP:                                                               
  4836.           if (type2 != NUMBER_SYMTYPE) ERR("not number expression");            
  4837.           type = NUMBER_SYMTYPE;                                                
  4838.           break;                                                                
  4839.      case ADD_OP:                                                               
  4840.           if (type2 != NUMBER_SYMTYPE) ERR("not number expression");            
  4841.           type = NUMBER_SYMTYPE;                                                
  4842.           break;                                                                
  4843.      case NOT_OP:                                                               
  4844.           if (type2 != FLAG_SYMTYPE)   ERR("not flag expression");              
  4845.           type = FLAG_SYMTYPE;                                                  
  4846.           break;                                                                
  4847.    }                                                                            
  4848.    return make_factor_c(np,bp,type2,c1,c2);                                     
  4849.  }                                                                              
  4850.                                                                                 
  4851.  /* d:  factor -> "(" exp ")" */                                                
  4852.                                                                                 
  4853.  if (get_lpar(np,bp)) {                                                         
  4854.    if (!(d1 = get_exp(np,bp))) ERR("expecting numeric expression");             
  4855.    if (!get_rpar(np,bp))       ERR("expecting right parenthesis");              
  4856.    type = d1->s;                                                                
  4857.    return make_factor_d(np,bp,type,d1);                                         
  4858.  }                                                                              
  4859.                                                                                 
  4860.  return NULL;                                                                   
  4861.                                                                                 
  4862. }                                                                               
  4863.                                                                                 
  4864. /*-------------------------------------------------------------------*/         
  4865.                                                                                 
  4866. static Term                                                                     
  4867. get_term(np,bp)                                                                 
  4868. Rstruc nncb     *np;                                                            
  4869. Rstruc batch    *bp;                                                            
  4870. {                                                                               
  4871.  Term            p;                                                             
  4872.  Factor          a1;                                                            
  4873.  Mulop           b2;                                                            
  4874.  Factor          b3;                                                            
  4875.  enum symtype    type;                                                          
  4876.  enum symtype    type1;                                                         
  4877.  enum symtype    type3;                                                         
  4878.                                                                                 
  4879.  /* a:  term -> factor */                                                       
  4880.                                                                                 
  4881.  if (!(a1 = get_factor(np,bp))) return NULL;                                    
  4882.                                                                                 
  4883.  type = a1->s;                                                                  
  4884.  p = make_term_a(np,bp,type,a1);                                                
  4885.                                                                                 
  4886.  /* b:  term -> term mulop factor */                                            
  4887.                                                                                 
  4888.  for (;;) {                                                                     
  4889.                                                                                 
  4890.    if (!(b2 = get_mulop(np,bp))) break;                                         
  4891.    if (!(b3 = get_factor(np,bp))) ERR("expecting numeric factor");              
  4892.    type1 = p->s;                                                                
  4893.    type3 = b3->s;                                                               
  4894.    if (type1!=NUMBER_SYMTYPE) ERR("operand 1 not number expression");           
  4895.    if (type3!=NUMBER_SYMTYPE) ERR("operand 2 not number expression");           
  4896.    type = NUMBER_SYMTYPE;                                                       
  4897.    p = make_term_b(np,bp,type,p,b2,b3);                                         
  4898.  }                                                                              
  4899.                                                                                 
  4900.  return p;                                                                      
  4901.                                                                                 
  4902. }                                                                               
  4903.                                                                                 
  4904. /*-------------------------------------------------------------------*/         
  4905.                                                                                 
  4906. static Quantity                                                                 
  4907. get_quantity(np,bp)                                                             
  4908. Rstruc nncb     *np;                                                            
  4909. Rstruc batch    *bp;                                                            
  4910. {                                                                               
  4911.  Quantity        p;                                                             
  4912.  Term            a1;                                                            
  4913.  Addop           b2;                                                            
  4914.  Term            b3;                                                            
  4915.  enum symtype    type;                                                          
  4916.  enum symtype    type1;                                                         
  4917.  enum symtype    type3;                                                         
  4918.                                                                                 
  4919.  /* a:  quantity -> term */                                                     
  4920.                                                                                 
  4921.  if (!(a1 = get_term(np,bp))) return NULL;                                      
  4922.                                                                                 
  4923.  type = a1->s;                                                                  
  4924.  p = make_quantity_a(np,bp,type,a1);                                            
  4925.                                                                                 
  4926.  /* b:  quantity -> quantity addop term */                                      
  4927.                                                                                 
  4928.  for (;;) {                                                                     
  4929.                                                                                 
  4930.    if (!(b2 = get_addop(np,bp))) break;                                         
  4931.    if (!(b3 = get_term(np,bp))) ERR("expecting numeric term");                  
  4932.    type1 = p->s;                                                                
  4933.    type3 = b3->s;                                                               
  4934.    if (type1!=NUMBER_SYMTYPE) ERR("operand 1 not number expression");           
  4935.    if (type3!=NUMBER_SYMTYPE) ERR("operand 2 not number expression");           
  4936.    type = NUMBER_SYMTYPE;                                                       
  4937.    p = make_quantity_b(np,bp,type,p,b2,b3);                                     
  4938.  }                                                                              
  4939.                                                                                 
  4940.  return p;                                                                      
  4941.                                                                                 
  4942. }                                                                               
  4943.                                                                                 
  4944. /*-------------------------------------------------------------------*/         
  4945.                                                                                 
  4946. static Value                                                                    
  4947. get_value(np,bp)                                                                
  4948. Rstruc nncb     *np;                                                            
  4949. Rstruc batch    *bp;                                                            
  4950. {                                                                               
  4951.  Value           p;                                                             
  4952.  Quantity        a1;                                                            
  4953.  Quantity        b2;                                                            
  4954.  enum symtype    type;                                                          
  4955.  enum symtype    type1;                                                         
  4956.  enum symtype    type2;                                                         
  4957.                                                                                 
  4958.  /* a:  value -> quantity */                                                    
  4959.                                                                                 
  4960.  if (!(a1 = get_quantity(np,bp))) return NULL;                                  
  4961.                                                                                 
  4962.  type = a1->s;                                                                  
  4963.  p = make_value_a(np,bp,type,a1);                                               
  4964.                                                                                 
  4965.  /* b:  value -> value quantity */                                              
  4966.                                                                                 
  4967.  for (;;) {                                                                     
  4968.                                                                                 
  4969.    if (!(b2 = get_quantity(np,bp))) break;                                      
  4970.    type1 = p->s;                                                                
  4971.    type2 = p->s;                                                                
  4972.    type = STRING_SYMTYPE;                                                       
  4973.    p = make_value_b(np,bp,type,p,b2);                                           
  4974.  }                                                                              
  4975.                                                                                 
  4976.  return p;                                                                      
  4977.                                                                                 
  4978. }                                                                               
  4979.                                                                                 
  4980. /*-------------------------------------------------------------------*/         
  4981.                                                                                 
  4982. static Relation                                                                 
  4983. get_relation(np,bp)                                                             
  4984. Rstruc nncb     *np;                                                            
  4985. Rstruc batch    *bp;                                                            
  4986. {                                                                               
  4987.  Relation        p;                                                             
  4988.  Value           a1;                                                            
  4989.  Relop           b2;                                                            
  4990.  Value           b3;                                                            
  4991.  enum symtype    type;                                                          
  4992.  enum symtype    type1;                                                         
  4993.  enum symtype    type3;                                                         
  4994.                                                                                 
  4995.  /* a:  relation -> value */                                                    
  4996.                                                                                 
  4997.  if (!(a1 = get_value(np,bp))) return NULL;                                     
  4998.                                                                                 
  4999.  type = a1->s;                                                                  
  5000.  p = make_relation_a(np,bp,type,a1);                                            
  5001.                                                                                 
  5002.  /* b:  relation -> value relop value */                                        
  5003.                                                                                 
  5004.  if (!(b2 = get_relop(np,bp))) return p;                                        
  5005.  if (!(b3 = get_value(np,bp)))                                                  
  5006.     ERR("expecting string or numeric value");                                   
  5007.  type1 = a1->s;                                                                 
  5008.  type3 = b3->s;                                                                 
  5009.  switch (b2->op1) {                                                             
  5010.    case IN_OP:                                                                  
  5011.      if (type1 != STRING_SYMTYPE)                                               
  5012.         ERR("operand 1 not string expression");                                 
  5013.      if (type3 != STRING_SYMTYPE)                                               
  5014.         ERR("operand 3 not string expression");                                 
  5015.      break;                                                                     
  5016.    case EQ_OP:                                                                  
  5017.    case NE_OP:                                                                  
  5018.      if (!((type1 == NUMBER_SYMTYPE && type3 == NUMBER_SYMTYPE)                 
  5019.         || (type1 == STRING_SYMTYPE && type3 == STRING_SYMTYPE)                 
  5020.         || (type1 == FLAG_SYMTYPE   && type3 == FLAG_SYMTYPE)))                 
  5021.       ERR("operands are not both of the same type");                            
  5022.      break;                                                                     
  5023.    default:                                                                     
  5024.      if (!((type1 == NUMBER_SYMTYPE && type3 == NUMBER_SYMTYPE)                 
  5025.         || (type1 == STRING_SYMTYPE && type3 == STRING_SYMTYPE)))               
  5026.       ERR("operands are not both numeric or both string expressions");          
  5027.      break;                                                                     
  5028.  }                                                                              
  5029.  type = FLAG_SYMTYPE;                                                           
  5030.  p = make_relation_b(np,bp,type,a1,b2,b3);                                      
  5031.                                                                                 
  5032.  return p;                                                                      
  5033.                                                                                 
  5034. }                                                                               
  5035.                                                                                 
  5036. /*-------------------------------------------------------------------*/         
  5037.                                                                                 
  5038. static Choice                                                                   
  5039. get_choice(np,bp)                                                               
  5040. Rstruc nncb     *np;                                                            
  5041. Rstruc batch    *bp;                                                            
  5042. {                                                                               
  5043.  Choice          p;                                                             
  5044.  Relation        a1;                                                            
  5045.  Logop           b2;                                                            
  5046.  Relation        b3;                                                            
  5047.  enum symtype    type;                                                          
  5048.  enum symtype    type1;                                                         
  5049.  enum symtype    type3;                                                         
  5050.                                                                                 
  5051.  /* a:  choice -> relation */                                                   
  5052.                                                                                 
  5053.  if (!(a1 = get_relation(np,bp))) return NULL;                                  
  5054.                                                                                 
  5055.  type = a1->s;                                                                  
  5056.  p = make_choice_a(np,bp,type,a1);                                              
  5057.                                                                                 
  5058.  /* b:  choice -> choice logop relation */                                      
  5059.                                                                                 
  5060.  for (;;) {                                                                     
  5061.                                                                                 
  5062.    if (!(b2 = get_logop(np,bp))) break;                                         
  5063.    if (!(b3 = get_relation(np,bp)))                                             
  5064.       ERR("expecting logical expression");                                      
  5065.    type1 = p->s;                                                                
  5066.    type3 = b3->s;                                                               
  5067.    if (type1 != FLAG_SYMTYPE) ERR("operand 1 not logical expression");          
  5068.    if (type3 != FLAG_SYMTYPE) ERR("operand 2 not logical expression");          
  5069.    type = FLAG_SYMTYPE;                                                         
  5070.    p = make_choice_b(np,bp,type,p,b2,b3);                                       
  5071.  }                                                                              
  5072.                                                                                 
  5073.  return p;                                                                      
  5074.                                                                                 
  5075. }                                                                               
  5076.                                                                                 
  5077. /*-------------------------------------------------------------------*/         
  5078.                                                                                 
  5079. static Exp                                                                      
  5080. get_exp(np,bp)                                                                  
  5081. Rstruc nncb     *np;                                                            
  5082. Rstruc batch    *bp;                                                            
  5083. {                                                                               
  5084.  Choice          a1;                                                            
  5085.  Exp             b1;                                                            
  5086.  Exp             b2;                                                            
  5087.  Exp             b3;                                                            
  5088.  enum symtype    type;                                                          
  5089.  enum symtype    type1;                                                         
  5090.  enum symtype    type2;                                                         
  5091.  enum symtype    type3;                                                         
  5092.                                                                                 
  5093.  /* b:  exp -> "IF" exp "THEN" exp "ELSE" exp */                                
  5094.                                                                                 
  5095.  if (get_word(np,bp,"IF")) {                                                    
  5096.    if (!(b1 = get_exp(np,bp)))    ERR("expecting expression");                  
  5097.    if (!(get_word(np,bp,"THEN"))) ERR("expecting THEN");                        
  5098.    if (!(b2 = get_exp(np,bp)))    ERR("expecting expression");                  
  5099.    if (!(get_word(np,bp,"ELSE"))) ERR("expecting ELSE");                        
  5100.    if (!(b3 = get_exp(np,bp)))    ERR("expecting expression");                  
  5101.    type1 = b1->s;                                                               
  5102.    type2 = b2->s;                                                               
  5103.    type3 = b3->s;                                                               
  5104.    if (type1 != FLAG_SYMTYPE) ERR("operand 1 not logical expression");          
  5105.    type = type2;                                                                
  5106.    return make_exp_b(np,bp,type,b1,b2,b3);                                      
  5107.  }                                                                              
  5108.                                                                                 
  5109.  /* a:  exp -> choice */                                                        
  5110.                                                                                 
  5111.  if (!(a1 = get_choice(np,bp))) ERR("expecting IF or expression");              
  5112.  type = a1->s;                                                                  
  5113.  return make_exp_a(np,bp,type,a1);                                              
  5114.                                                                                 
  5115. }                                                                               
  5116.                                                                                 
  5117. /*-------------------------------------------------------------------*/         
  5118.                                                                                 
  5119. static Exp                                                                      
  5120. get_strtree(np,bp)                                                              
  5121. Rstruc nncb     *np;                                                            
  5122. Rstruc batch    *bp;                                                            
  5123. {                                                                               
  5124.  Exp             p;                                                             
  5125.                                                                                 
  5126.  p = get_exp(np,bp);                                                            
  5127.  if (!p) {                                                                      
  5128.   NNMbsynt(np,bp,NULL,0,"no expression found");                                 
  5129.   return NULL;                                                                  
  5130.  }                                                                              
  5131.                                                                                 
  5132.  return p;                                                                      
  5133. }                                                                               
  5134.                                                                                 
  5135. /*-------------------------------------------------------------------*/         
  5136.                                                                                 
  5137. static Exp                                                                      
  5138. get_numtree(np,bp)                                                              
  5139. Rstruc nncb     *np;                                                            
  5140. Rstruc batch    *bp;                                                            
  5141. {                                                                               
  5142.  Exp             p;                                                             
  5143.                                                                                 
  5144.  p = get_exp(np,bp);                                                            
  5145.  if (!p) {                                                                      
  5146.    NNMbsynt(np,bp,NULL,0,"no expression found");                                
  5147.    return NULL;                                                                 
  5148.  }                                                                              
  5149.  switch (p->s) {                                                                
  5150.    case STRING_SYMTYPE:                                                         
  5151.         NNMbsynt(np,bp,NULL,0,"numeric expression required");                   
  5152.         return NULL;                                                            
  5153.    case NUMBER_SYMTYPE:                                                         
  5154.    case FLAG_SYMTYPE:                                                           
  5155.    default:             return p;                                               
  5156.  }                                                                              
  5157. }                                                                               
  5158.                                                                                 
  5159. /*-------------------------------------------------------------------*/         
  5160.                                                                                 
  5161. static Exp                                                                      
  5162. get_flagtree(np,bp)                                                             
  5163. Rstruc nncb     *np;                                                            
  5164. Rstruc batch    *bp;                                                            
  5165. {                                                                               
  5166.  Exp             p;                                                             
  5167.                                                                                 
  5168.  p = get_exp(np,bp);                                                            
  5169.  if (!p) {                                                                      
  5170.    NNMbsynt(np,bp,NULL,0,"no expression found");                                
  5171.    return NULL;                                                                 
  5172.  }                                                                              
  5173.  switch (p->s) {                                                                
  5174.    case FLAG_SYMTYPE:  return p;                                                
  5175.    default:                                                                     
  5176.             NNMbsynt(np,bp,NULL,0,"logical expression required");               
  5177.             return NULL;                                                        
  5178.  }                                                                              
  5179. }                                                                               
  5180.                                                                                 
  5181. /****** Get expression and build an expression tree. *****************/         
  5182.                                                                                 
  5183. struct ptree *                                                                  
  5184. NNMbgexp(np,bp,type)                                                            
  5185. Rstruc nncb         *np;                                                        
  5186. Rstruc batch        *bp;                                                        
  5187. enum symtype         type;                                                      
  5188. {                                                                               
  5189.  struct ptree       *treep      = NULL;                                         
  5190.                                                                                 
  5191.  /* Define return point for syntax errors during parse. */                      
  5192.                                                                                 
  5193.  switch (setjmp(bp->jump)) {                                                    
  5194.    case ERROR_NONE:                                                             
  5195.         break;                                                                  
  5196.    case ERROR_GETMAIN_FAILURE:                                                  
  5197.         NNMbsynt(np,bp,NULL,0,"Not enough memory to parse expression");         
  5198.         return NULL;                                                            
  5199.    default:                                                                     
  5200.         bp->syntax_error = TRUE;                                                
  5201.         return NULL;                                                            
  5202.  }                                                                              
  5203.                                                                                 
  5204.  switch (type) {                                                                
  5205.    case STRING_SYMTYPE:                                                         
  5206.                         GETMAIN(treep,struct ptree,1,"string ptree");           
  5207.                         if (treep) {                                            
  5208.                           treep->type = STRING_TREETYPE;                        
  5209.                           treep->exp1 = get_strtree(np,bp);                     
  5210.                         }                                                       
  5211.                         break;                                                  
  5212.    case NUMBER_SYMTYPE:                                                         
  5213.                         GETMAIN(treep,struct ptree,1,"number ptree");           
  5214.                         if (treep) {                                            
  5215.                           treep->type = NUMBER_TREETYPE;                        
  5216.                           treep->exp1 = get_numtree(np,bp);                     
  5217.                         }                                                       
  5218.                         break;                                                  
  5219.    case FLAG_SYMTYPE:                                                           
  5220.                         GETMAIN(treep,struct ptree,1,"flag ptree");             
  5221.                         if (treep) {                                            
  5222.                           treep->type       = FLAG_TREETYPE;                    
  5223.                           treep->exp1 = get_flagtree(np,bp);                    
  5224.                         }                                                       
  5225.                         break;                                                  
  5226.    default: NNMbsynt(np,bp,NULL,0,"Invalid type passed to NNMbgexp");           
  5227.             return NULL;                                                        
  5228.  }                                                                              
  5229.                                                                                 
  5230.  if (!treep) {                                                                  
  5231.    NNMbsynt(np,bp,NULL,0,"No storage available to build expression");           
  5232.    return NULL;                                                                 
  5233.  }                                                                              
  5234.                                                                                 
  5235.  return treep;                                                                  
  5236. }                                                                               
  5237.                                                                                 
  5238. ./   ADD NAME=NNMBGTOK,SSI=010E0027                                             
  5239.                                                                                 
  5240.  /********************************************************************/         
  5241.  /*                                                                  */         
  5242.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5243.  /*                                                                  */         
  5244.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5245.  /* including the implied warranties of merchantability and fitness, */         
  5246.  /* are expressly denied.                                            */         
  5247.  /*                                                                  */         
  5248.  /* Provided this copyright notice is included, this software may    */         
  5249.  /* be freely distributed and not offered for sale.                  */         
  5250.  /*                                                                  */         
  5251.  /* Changes or modifications may be made and used only by the maker  */         
  5252.  /* of same, and not further distributed.  Such modifications should */         
  5253.  /* be mailed to the author for consideration for addition to the    */         
  5254.  /* software and incorporation in subsequent releases.               */         
  5255.  /*                                                                  */         
  5256.  /********************************************************************/         
  5257.                                                                                 
  5258. #pragma  csect(code,  "NN@BGTOK")                                               
  5259. #pragma  csect(static,"NN$BGTOK")                                               
  5260. #include "nn.h"                                                                 
  5261. #include "nnbatch.h"                                                            
  5262.                                                                                 
  5263. /****** Get input line. **********************************************/         
  5264.                                                                                 
  5265. static char *                                                                   
  5266. get_input_line(np,bp)                                                           
  5267. Rstruc nncb         *np;                                                        
  5268. Rstruc batch        *bp;                                                        
  5269. {                                                                               
  5270.  char               *cp;                                                        
  5271.                                                                                 
  5272.  for (;;) {                                                                     
  5273.                                                                                 
  5274.    cp = fgets(bp->inline, sizeof(bp->inline), np->batch_infile);                
  5275.                                                                                 
  5276.    if (!cp) {                                                                   
  5277.      if (ferror(np->batch_infile)) {                                            
  5278.        fprintf(stderr,"\n*** Error reading batch input file ***\n");            
  5279.        abort();                                                                 
  5280.      }                                                                          
  5281.      bp->eof = TRUE;                                                            
  5282.      return NULL;                                                               
  5283.    }                                                                            
  5284.                                                                                 
  5285.    else if ((cp=strchr(cp,'\n'))) *cp = '\0';                                   
  5286.                                                                                 
  5287.    /* Hack to allow standard entry of EOF from the terminal. */                 
  5288.                                                                                 
  5289.    if (EQUAL(bp->inline,"/*")) {                                                
  5290.      fprintf(np->batch_outfile, "EOF (/*) signalled in input.\n");              
  5291.      bp->eof = TRUE;                                                            
  5292.      return NULL;                                                               
  5293.    }                                                                            
  5294.                                                                                 
  5295.    fprintf(np->batch_outfile, "%s\n", bp->inline);                              
  5296.                                                                                 
  5297.    if (bp->inline[0] != '#') break;                                             
  5298.                                                                                 
  5299.  }                                                                              
  5300.                                                                                 
  5301.  return bp->inline;                                                             
  5302.                                                                                 
  5303. }                                                                               
  5304.                                                                                 
  5305. /****** Show token, for debugging only. ******************************/         
  5306.                                                                                 
  5307. static char *                                                                   
  5308. token_description(tokp)                                                         
  5309. struct token     *tokp;                                                         
  5310. {                                                                               
  5311.                                                                                 
  5312.  switch (tokp->type) {                                                          
  5313.                      case NO_TOKEN:       return "no token";                    
  5314.                      case EOL_TOKEN:      return "EOL";                         
  5315.                      case EOF_TOKEN:      return "EOF";                         
  5316.                      case AND_TOKEN:      return "AND";                         
  5317.                      case OR_TOKEN:       return "OR";                          
  5318.                      case NOT_TOKEN:      return "NOT";                         
  5319.                      case GT_TOKEN:       return "GT";                          
  5320.                      case LT_TOKEN:       return "LT";                          
  5321.                      case EQ_TOKEN:       return "EQ";                          
  5322.                      case NE_TOKEN:       return "NE";                          
  5323.                      case GE_TOKEN:       return "GE";                          
  5324.                      case LE_TOKEN:       return "LE";                          
  5325.                      case LPAR_TOKEN:     return "LPAR";                        
  5326.                      case RPAR_TOKEN:     return "RPAR";                        
  5327.                      case PLUS_TOKEN:     return "PLUS";                        
  5328.                      case MINUS_TOKEN:    return "MINUS";                       
  5329.                      case TIMES_TOKEN:    return "TIMES";                       
  5330.                      case OVER_TOKEN:     return "OVER";                        
  5331.                      case SEMI_TOKEN:     return "SEMI";                        
  5332.                      case WORD_TOKEN:     return "WORD";                        
  5333.                      case NUMBER_TOKEN:   return "NUMBER";                      
  5334.                      case STRING_TOKEN:   return "STRING";                      
  5335.                      case ERROR_TOKEN:    return "ERROR";                       
  5336.                      default:             return "?";                           
  5337.                 }                                                               
  5338. }                                                                               
  5339.                                                                                 
  5340. /****** Get token. ***************************************************/         
  5341.                                                                                 
  5342. static Bool                                                                     
  5343. get_token(np,bp,tokp,flushing)                                                  
  5344. Rstruc nncb         *np;                                                        
  5345. Rstruc batch        *bp;                                                        
  5346. struct token        *tokp;                                                      
  5347. Fool                 flushing;                                                  
  5348. {                                                                               
  5349.  char               *cp;                                                        
  5350.  char               *dp;                                                        
  5351.  char               *ep;                                                        
  5352.  int                 len;                                                       
  5353.  Bool                inquote;                                                   
  5354.  Bool                badtoken;                                                  
  5355.                                                                                 
  5356.  /* If reached end of current line, get a line */                               
  5357.                                                                                 
  5358.  do {                                                                           
  5359.    while (*bp->inchar == '\0') {                                                
  5360.      if (bp->stop_at_newline) {                                                 
  5361.        tokp->type = EOL_TOKEN;                                                  
  5362.        strcpy(tokp->string,"<**End Of Line**>");                                
  5363.        return TRUE;                                                             
  5364.      }                                                                          
  5365.      bp->inchar = get_input_line(np,bp);                                        
  5366.      if (bp->inchar == NULL) {                                                  
  5367.        tokp->type = EOF_TOKEN;                                                  
  5368.        strcpy(tokp->string,"<**End Of File**>");                                
  5369.        return TRUE;                                                             
  5370.      }                                                                          
  5371.    }                                                                            
  5372.    while (isspace(*bp->inchar)) bp->inchar++;                                   
  5373.    if (*bp->inchar == '#') *bp->inchar = '\0';                                  
  5374.  } while (*bp->inchar == '\0');                                                 
  5375.                                                                                 
  5376.  memset(tokp->string, 0, sizeof(tokp->string));                                 
  5377.  tokp->number = 0;                                                              
  5378.  bp->syntax_error = FALSE;                                                      
  5379.  badtoken = FALSE;                                                              
  5380.                                                                                 
  5381.  cp = bp->inchar;                                                               
  5382.  if (isdigit(*cp)) {                                                            
  5383.    ep = cp + strspn(cp,"0123456789");                                           
  5384.    len = ep - cp;                                                               
  5385.    bp->inchar = ep;                                                             
  5386.    if (len > 10) {                                                              
  5387.      badtoken = TRUE;                                                           
  5388.      if (flushing) tokp->type = ERROR_TOKEN;                                    
  5389.      else NNMbsynt(np,bp,cp,len,"Number too long");                             
  5390.    }                                                                            
  5391.    else {                                                                       
  5392.      tokp->type = NUMBER_TOKEN;                                                 
  5393.      memcpy(tokp->string, cp, len);                                             
  5394.      tokp->number = atoi(tokp->string);                                         
  5395.    }                                                                            
  5396.  }                                                                              
  5397.  else if (isalpha(*cp)) {                                                       
  5398.    dp = tokp->string;                                                           
  5399.    ep = dp + sizeof(tokp->string) - 1;                                          
  5400.    while (isalnum(*cp)) {                                                       
  5401.      if (dp > ep) {                                                             
  5402.        if (!badtoken) {                                                         
  5403.          badtoken = TRUE;                                                       
  5404.          if (flushing) tokp->type = ERROR_TOKEN;                                
  5405.          else NNMbsynt(np,bp,cp,ep-cp, "Word too long");                        
  5406.        }                                                                        
  5407.      }                                                                          
  5408.      else {                                                                     
  5409.        *(dp++) = toupper(*(cp++));                                              
  5410.      }                                                                          
  5411.    }                                                                            
  5412.    *dp = '\0';                                                                  
  5413.    bp->inchar = cp;                                                             
  5414.    tokp->type = badtoken ? ERROR_TOKEN : WORD_TOKEN;                            
  5415.  }                                                                              
  5416.  else if (*cp == '"') {                                                         
  5417.    bp->inchar++;                                                                
  5418.    cp = bp->inchar;                                                             
  5419.    dp = tokp->string;                                                           
  5420.    ep = tokp->string + sizeof(tokp->string) - 1;                                
  5421.    inquote = TRUE;                                                              
  5422.    while (inquote) {                                                            
  5423.      switch (*cp) {                                                             
  5424.        case '\0': NNMbsynt(np,bp,NULL,0,"Missing end quote");                   
  5425.                   inquote = FALSE;                                              
  5426.                   bp->inchar = cp;                                              
  5427.                   break;                                                        
  5428.        case '"' : inquote = FALSE;                                              
  5429.                   bp->inchar = cp+1;                                            
  5430.                   break;                                                        
  5431.        case '\\': cp++;                                                         
  5432.                   /* fall through */                                            
  5433.        default  : if (dp > ep) {                                                
  5434.                     if (!badtoken) {                                            
  5435.                       badtoken = TRUE;                                          
  5436.                       if (flushing) tokp->type = ERROR_TOKEN;                   
  5437.                       else NNMbsynt(np,bp,NULL,0,                               
  5438.                                     "Quoted string too long");                  
  5439.                     }                                                           
  5440.                   }                                                             
  5441.                   else {                                                        
  5442.                     *(dp++) = *(cp++);                                          
  5443.                   }                                                             
  5444.                   break;                                                        
  5445.      }                                                                          
  5446.    }                                                                            
  5447.    *dp = '\0';                                                                  
  5448.    tokp->type = badtoken ? ERROR_TOKEN : STRING_TOKEN;                          
  5449.  }                                                                              
  5450.  else {                                                                         
  5451.    switch (*cp) {                                                               
  5452.      case ';': bp->inchar++; tokp->type = SEMI_TOKEN;  break;                   
  5453.      case '(': bp->inchar++; tokp->type = LPAR_TOKEN;  break;                   
  5454.      case ')': bp->inchar++; tokp->type = RPAR_TOKEN;  break;                   
  5455.      case '+': bp->inchar++; tokp->type = PLUS_TOKEN;  break;                   
  5456.      case '-': bp->inchar++; tokp->type = MINUS_TOKEN; break;                   
  5457.      case '*': bp->inchar++; tokp->type = TIMES_TOKEN; break;                   
  5458.      case '/': bp->inchar++; tokp->type = OVER_TOKEN;  break;                   
  5459.      case '&': bp->inchar++; tokp->type = AND_TOKEN;   break;                   
  5460.      case '|': bp->inchar++; tokp->type = OR_TOKEN;    break;                   
  5461.      case '>': bp->inchar++;                                                    
  5462.                switch (*bp->inchar) {                                           
  5463.                  case '=': bp->inchar++; tokp->type = GE_TOKEN; break;          
  5464.                  default:                tokp->type = GT_TOKEN; break;          
  5465.                }                                                                
  5466.                break;                                                           
  5467.      case '<': bp->inchar++;                                                    
  5468.                switch (*bp->inchar) {                                           
  5469.                  case '=': bp->inchar++; tokp->type = LE_TOKEN; break;          
  5470.                  case '>': bp->inchar++; tokp->type = NE_TOKEN; break;          
  5471.                  default:                tokp->type = LT_TOKEN; break;          
  5472.                }                                                                
  5473.                break;                                                           
  5474.      case '=': bp->inchar++;                                                    
  5475.                switch (*bp->inchar) {                                           
  5476.                  case '=': bp->inchar++; tokp->type = EQ_TOKEN; break;          
  5477.                  default:                tokp->type = EQ_TOKEN; break;          
  5478.                }                                                                
  5479.                break;                                                           
  5480.      case '^':                                                                  
  5481.      case '!': bp->inchar++;                                                    
  5482.                switch (*bp->inchar) {                                           
  5483.                  case '=': bp->inchar++; tokp->type = NE_TOKEN; break;          
  5484.                  case '<': bp->inchar++; tokp->type = GT_TOKEN; break;          
  5485.                  case '>': bp->inchar++; tokp->type = LT_TOKEN; break;          
  5486.                  default:                tokp->type = NOT_TOKEN; break;         
  5487.                }                                                                
  5488.                break;                                                           
  5489.      default:  if (flushing) tokp->type = ERROR_TOKEN;                          
  5490.                else NNMbsynt(np,bp,cp,1,                                        
  5491.                              "Invalid character, cannot scan");                 
  5492.                bp->inchar++;                                                    
  5493.                break;                                                           
  5494.    }                                                                            
  5495.    memcpy(tokp->string, cp, bp->inchar - cp); /* just in case */                
  5496.  }                                                                              
  5497.                                                                                 
  5498.  if (np->debug_file) {                                                          
  5499.    fprintf(np->debug_file,"token = %s", token_description(tokp));               
  5500.    switch (tokp->type) {                                                        
  5501.      case NUMBER_TOKEN:                                                         
  5502.             fprintf(np->debug_file, "(%d,'%s')\n", tokp->number,                
  5503.                                                    tokp->string);               
  5504.             break;                                                              
  5505.      case WORD_TOKEN:                                                           
  5506.      case STRING_TOKEN:                                                         
  5507.      default:                                                                   
  5508.             fprintf(np->debug_file, "(%s)\n", tokp->string);                    
  5509.             break;                                                              
  5510.    }                                                                            
  5511.  }                                                                              
  5512.                                                                                 
  5513.  return TRUE;                                                                   
  5514.                                                                                 
  5515. }                                                                               
  5516.                                                                                 
  5517. /****** Get token. ***************************************************/         
  5518.                                                                                 
  5519. Bool                                                                            
  5520. NNMbgtok(np,bp,func)                                                            
  5521. Rstruc nncb         *np;                                                        
  5522. Rstruc batch        *bp;                                                        
  5523. enum tokenfunc       func;                                                      
  5524. {                                                                               
  5525.                                                                                 
  5526.  if (!bp->tokens_read) {                                                        
  5527.    bp->inchar = get_input_line(np,bp);                                          
  5528.    bp->tokens_read = TRUE;                                                      
  5529.    if (bp->inchar == NULL) { /* no input at all? */                             
  5530.      bp->curtok.type = EOF_TOKEN;                                               
  5531.      bp->nextok.type = EOF_TOKEN;                                               
  5532.      return TRUE;                                                               
  5533.    }                                                                            
  5534.  }                                                                              
  5535.  if (bp->curtok.type == EOF_TOKEN) {                                            
  5536.    NNMbsynt(np,bp,NULL,0, "Attempt to read token past end of file");            
  5537.    return FALSE;                                                                
  5538.  }                                                                              
  5539.                                                                                 
  5540.  switch (func) {                                                                
  5541.    case TOKEN_PEEK:                                                             
  5542.                      if (bp->nextok.type == NO_TOKEN) {                         
  5543.                        return get_token(np,bp,&bp->nextok,FALSE);               
  5544.                      }                                                          
  5545.                      else { /* token already peeked at */                       
  5546.                        return TRUE;                                             
  5547.                      }                                                          
  5548.    case TOKEN_READ:                                                             
  5549.                      if (bp->nextok.type == NO_TOKEN) {                         
  5550.                        return get_token(np,bp,&bp->curtok,FALSE);               
  5551.                      }                                                          
  5552.                      else { /* token already peeked at */                       
  5553.                        memcpy((char *)&bp->curtok,                              
  5554.                               (char *)&bp->nextok,                              
  5555.                               sizeof(struct token));                            
  5556.                        bp->nextok.type = NO_TOKEN;                              
  5557.                        return TRUE;                                             
  5558.                      }                                                          
  5559.    case TOKEN_FLUSH:                                                            
  5560.                      if (bp->nextok.type == NO_TOKEN) {                         
  5561.                        return get_token(np,bp,&bp->curtok,TRUE);                
  5562.                      }                                                          
  5563.                      else { /* token already peeked at */                       
  5564.                        memcpy((char *)&bp->curtok,                              
  5565.                               (char *)&bp->nextok,                              
  5566.                               sizeof(struct token));                            
  5567.                        bp->nextok.type = NO_TOKEN;                              
  5568.                        return TRUE;                                             
  5569.                      }                                                          
  5570.  }                                                                              
  5571.                                                                                 
  5572. }                                                                               
  5573.                                                                                 
  5574. ./   ADD NAME=NNMBPDEC,SSI=01030055                                             
  5575.                                                                                 
  5576.  /********************************************************************/         
  5577.  /*                                                                  */         
  5578.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5579.  /*                                                                  */         
  5580.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5581.  /* including the implied warranties of merchantability and fitness, */         
  5582.  /* are expressly denied.                                            */         
  5583.  /*                                                                  */         
  5584.  /* Provided this copyright notice is included, this software may    */         
  5585.  /* be freely distributed and not offered for sale.                  */         
  5586.  /*                                                                  */         
  5587.  /* Changes or modifications may be made and used only by the maker  */         
  5588.  /* of same, and not further distributed.  Such modifications should */         
  5589.  /* be mailed to the author for consideration for addition to the    */         
  5590.  /* software and incorporation in subsequent releases.               */         
  5591.  /*                                                                  */         
  5592.  /********************************************************************/         
  5593.                                                                                 
  5594. /*=====================================================================         
  5595.  *                                                                              
  5596.  * Command: DECLARE                                                             
  5597.  *                                                                              
  5598.  * Syntax:  DECLARE variablename {STRING | NUMBER | FLAG}                       
  5599.  *                                                                              
  5600.  * Mode:    any                                                                 
  5601.  *                                                                              
  5602.  * Function: Declares a variable that can be referenced later.                  
  5603.  *           Its type is specified as well.  The type can be:                   
  5604.  *                                                                              
  5605.  *           * STRING - character string                                        
  5606.  *           * NUMBER - integer                                                 
  5607.  *           * FLAG   - 1 or 0, TRUE or FALSE, ON or OFF, YES or NO             
  5608.  *                                                                              
  5609.  * Note: This command is processed at parse time only.  It is not an            
  5610.  *       executable command.  No matter where it appears in the input           
  5611.  *       command environment, it will be processed.  The only caveat            
  5612.  *       is that a variable must be referenced by DECLARE prior to              
  5613.  *       any appearance of it in the input stream.                              
  5614.  *                                                                              
  5615.  * Examples:  DECLARE FOO STRING                                                
  5616.  *            DECLARE BAR NUMBER                                                
  5617.  *            DECLARE BAZ FLAG                                                  
  5618.  *                                                                              
  5619.  *====================================================================*/        
  5620.                                                                                 
  5621. #pragma  csect(code,  "NN@BPDEC")                                               
  5622. #pragma  csect(static,"NN$BPDEC")                                               
  5623. #include "nn.h"                                                                 
  5624. #include "nnbatch.h"                                                            
  5625.                                                                                 
  5626. /****** Parse batch DECLARE      command. ****************************/         
  5627.                                                                                 
  5628. struct newscmd *                                                                
  5629. NNMbpdec(np,bp)                                                                 
  5630. Rstruc nncb         *np;                                                        
  5631. Rstruc batch        *bp;                                                        
  5632. {                                                                               
  5633.  char               *var;                                                       
  5634.  enum symtype        type;                                                      
  5635.  ANYTYPE             val;                                                       
  5636.                                                                                 
  5637.  /*                                                                             
  5638.   * Next token must be variable name.                                           
  5639.   */                                                                            
  5640.                                                                                 
  5641.  (void)NNMbgtok(np,bp,TOKEN_READ);          /* get token */                     
  5642.  if (bp->curtok.type != WORD_TOKEN) {                                           
  5643.    NNMbsynt(np,bp,NULL,0,                                                       
  5644.             "Expected DECLARE variable name not seen");                         
  5645.    NNMbflus(np,bp);                         /* flush input tokens */            
  5646.    return NULL;                                                                 
  5647.  }                                                                              
  5648.                                                                                 
  5649.  var = NNMcopy(np,bp->curtok.string);                                           
  5650.                                                                                 
  5651.  /*                                                                             
  5652.   * Next token must be one of the words STRING, NUMBER or FLAG.                 
  5653.   *                                                                             
  5654.   */                                                                            
  5655.                                                                                 
  5656.  (void)NNMbgtok(np,bp,TOKEN_READ);          /* get token */                     
  5657.  if (bp->curtok.type != WORD_TOKEN) {                                           
  5658.    NNMbsynt(np,bp,NULL,0,                                                       
  5659.             "Expected DECLARE type name not seen");                             
  5660.    NNMbflus(np,bp);                         /* flush input tokens */            
  5661.    return NULL;                                                                 
  5662.  }                                                                              
  5663.                                                                                 
  5664.  if      (EQUAL(bp->curtok.string,"STRING")) {                                  
  5665.    type = STRING_SYMTYPE;                                                       
  5666.    val  = (ANYTYPE)"";                                                          
  5667.  }                                                                              
  5668.  else if (EQUAL(bp->curtok.string,"NUMBER")) {                                  
  5669.    type = NUMBER_SYMTYPE;                                                       
  5670.    val  = (ANYTYPE)0;                                                           
  5671.  }                                                                              
  5672.  else if (EQUAL(bp->curtok.string,"FLAG")) {                                    
  5673.    type = FLAG_SYMTYPE;                                                         
  5674.    val  = (ANYTYPE)0;                                                           
  5675.  }                                                                              
  5676.  else {                                                                         
  5677.   NNMbsynt(np,bp,bp->curtok.string,0,                                           
  5678.            "DECLARE type not one of STRING, NUMBER or FLAG");                   
  5679.   return NULL;                                                                  
  5680.  }                                                                              
  5681.                                                                                 
  5682.  if (!NNMbdecl(np,bp,var,type,val)) {                                           
  5683.   NNMbsynt(np,bp,var,0,                                                         
  5684.            "Declaration failed");                                               
  5685.   return NULL;                                                                  
  5686.  }                                                                              
  5687.                                                                                 
  5688.  return NULL;                                                                   
  5689. }                                                                               
  5690.                                                                                 
  5691. ./   ADD NAME=NNMBPDER,SSI=010D0017                                             
  5692.                                                                                 
  5693.  /********************************************************************/         
  5694.  /*                                                                  */         
  5695.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5696.  /*                                                                  */         
  5697.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5698.  /* including the implied warranties of merchantability and fitness, */         
  5699.  /* are expressly denied.                                            */         
  5700.  /*                                                                  */         
  5701.  /* Provided this copyright notice is included, this software may    */         
  5702.  /* be freely distributed and not offered for sale.                  */         
  5703.  /*                                                                  */         
  5704.  /* Changes or modifications may be made and used only by the maker  */         
  5705.  /* of same, and not further distributed.  Such modifications should */         
  5706.  /* be mailed to the author for consideration for addition to the    */         
  5707.  /* software and incorporation in subsequent releases.               */         
  5708.  /*                                                                  */         
  5709.  /********************************************************************/         
  5710.                                                                                 
  5711. /*=====================================================================         
  5712.  *                                                                              
  5713.  * Command: DEREGISTER                                                          
  5714.  *                                                                              
  5715.  * Syntax:  DEREGISTER                                                          
  5716.  *                                                                              
  5717.  * Mode:    per_newsgroup                                                       
  5718.  *                                                                              
  5719.  * Function: Deregisters the current newsgroup.                                 
  5720.  *                                                                              
  5721.  * Note: Arguments are not permitted.  If they are given, the                   
  5722.  *       function will not be performed.                                        
  5723.  *                                                                              
  5724.  * Examples:  DEREGISTER                                                        
  5725.  *                                                                              
  5726.  *====================================================================*/        
  5727.                                                                                 
  5728. #pragma  csect(code,  "NN@BPDER")                                               
  5729. #pragma  csect(static,"NN$BPDER")                                               
  5730. #include "nn.h"                                                                 
  5731. #include "nnbatch.h"                                                            
  5732.                                                                                 
  5733. /****** Execute batch DEREGISTER command. ****************************/         
  5734.                                                                                 
  5735. static void                                                                     
  5736. NNMbxder(np,bp,cmdp)                                                            
  5737. Rstruc nncb         *np;                                                        
  5738. Rstruc batch        *bp;                                                        
  5739. Rstruc newscmd      *cmdp;                                                      
  5740. {                                                                               
  5741.  Rstruc newsgroup   *gp = bp->gp;                                               
  5742.                                                                                 
  5743.  gp->registered = 0;                                                            
  5744.                                                                                 
  5745.  fprintf(np->batch_outfile,"Newsgroup %s deregistered.\n",gp->name);            
  5746.                                                                                 
  5747.  NNMsave(np,NULL);    /* Checkpoint NEWSRC file */                              
  5748.                                                                                 
  5749.  return;                                                                        
  5750.                                                                                 
  5751. }                                                                               
  5752.                                                                                 
  5753. /****** Parse batch DEREGISTER command. ****************************/           
  5754.                                                                                 
  5755. struct newscmd *                                                                
  5756. NNMbpder(np,bp)                                                                 
  5757. Rstruc nncb         *np;                                                        
  5758. Rstruc batch        *bp;                                                        
  5759. {                                                                               
  5760.  struct newscmd     *cmdp;                                                      
  5761.                                                                                 
  5762.  bp->stop_at_newline = TRUE;                                                    
  5763.                                                                                 
  5764.  NNMbtras(np,bp,"DEREGISTER");   /* Trash extraneous parameters */              
  5765.                                                                                 
  5766.  if (bp->syntax_error) return NULL;                                             
  5767.                                                                                 
  5768.  if (bp->mode != PER_NEWSGROUP_MODE) {                                          
  5769.    NNMbsynt(np,bp,NULL,0,                                                       
  5770.             "DEREGISTER is invalid outside of per-newsgroup mode");             
  5771.    return NULL;                                                                 
  5772.  }                                                                              
  5773.                                                                                 
  5774.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for DEREGISTER command");            
  5775.                                                                                 
  5776.  if (cmdp) {                                                                    
  5777.    cmdp->mode = PER_NEWSGROUP_MODE;                                             
  5778.    cmdp->proc = NNMbxder;                                                       
  5779.  }                                                                              
  5780.                                                                                 
  5781.  return cmdp;                                                                   
  5782.                                                                                 
  5783. }                                                                               
  5784.                                                                                 
  5785. ./   ADD NAME=NNMBPELS,SSI=01070036                                             
  5786.                                                                                 
  5787.  /********************************************************************/         
  5788.  /*                                                                  */         
  5789.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5790.  /*                                                                  */         
  5791.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5792.  /* including the implied warranties of merchantability and fitness, */         
  5793.  /* are expressly denied.                                            */         
  5794.  /*                                                                  */         
  5795.  /* Provided this copyright notice is included, this software may    */         
  5796.  /* be freely distributed and not offered for sale.                  */         
  5797.  /*                                                                  */         
  5798.  /* Changes or modifications may be made and used only by the maker  */         
  5799.  /* of same, and not further distributed.  Such modifications should */         
  5800.  /* be mailed to the author for consideration for addition to the    */         
  5801.  /* software and incorporation in subsequent releases.               */         
  5802.  /*                                                                  */         
  5803.  /********************************************************************/         
  5804.                                                                                 
  5805. #pragma  csect(code,  "NN@BPELS")                                               
  5806. #pragma  csect(static,"NN$BPELS")                                               
  5807. #include "nn.h"                                                                 
  5808. #include "nnbatch.h"                                                            
  5809.                                                                                 
  5810. /****** Parse batch ELSE         command. ****************************/         
  5811.                                                                                 
  5812. struct newscmd *                                                                
  5813. NNMbpels(np,bp)                                                                 
  5814. Rstruc nncb         *np;                                                        
  5815. Rstruc batch        *bp;                                                        
  5816. {                                                                               
  5817.  struct newscmd             *cmdp       = NULL;                                 
  5818.  struct cmdtree             *elsecmds   = NULL;                                 
  5819.                                                                                 
  5820.  cmdp = bp->ifcmd;                                                              
  5821.  bp->ifcmd = NULL;                                                              
  5822.                                                                                 
  5823.  if (!cmdp) {                                                                   
  5824.    NNMbsynt(np,bp,NULL,0,"ELSE without matching IF found");                     
  5825.  }                                                                              
  5826.                                                                                 
  5827.  /* Get DO-END command group.  */                                               
  5828.                                                                                 
  5829.  elsecmds = NNMbgdo(np,bp,bp->mode);                                            
  5830.                                                                                 
  5831.  if (bp->syntax_error) return NULL;                                             
  5832.                                                                                 
  5833.  if (cmdp) {                                                                    
  5834.    cmdp->cmd.fcmd.elsecmds = elsecmds;                                          
  5835.  }                                                                              
  5836.                                                                                 
  5837.  return NULL;  /* cmdp was already returned by IF */                            
  5838.                                                                                 
  5839. }                                                                               
  5840.                                                                                 
  5841. ./   ADD NAME=NNMBPEXE,SSI=010B0056                                             
  5842.                                                                                 
  5843.  /********************************************************************/         
  5844.  /*                                                                  */         
  5845.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5846.  /*                                                                  */         
  5847.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5848.  /* including the implied warranties of merchantability and fitness, */         
  5849.  /* are expressly denied.                                            */         
  5850.  /*                                                                  */         
  5851.  /* Provided this copyright notice is included, this software may    */         
  5852.  /* be freely distributed and not offered for sale.                  */         
  5853.  /*                                                                  */         
  5854.  /* Changes or modifications may be made and used only by the maker  */         
  5855.  /* of same, and not further distributed.  Such modifications should */         
  5856.  /* be mailed to the author for consideration for addition to the    */         
  5857.  /* software and incorporation in subsequent releases.               */         
  5858.  /*                                                                  */         
  5859.  /********************************************************************/         
  5860.                                                                                 
  5861. /*=====================================================================         
  5862.  *                                                                              
  5863.  * Command: EXEC                                                                
  5864.  *                                                                              
  5865.  * Syntax:  EXEC {datum}* ;                                                     
  5866.  *                                                                              
  5867.  * Mode:    any (but see note)                                                  
  5868.  *                                                                              
  5869.  * Function: Executes the TSO command built from the specified                  
  5870.  *           data items.  Items can be:                                         
  5871.  *                                                                              
  5872.  *           * text strings                                                     
  5873.  *           * integers                                                         
  5874.  *           * words representing variables that have values                    
  5875.  *                                                                              
  5876.  * Note: When words are used, the values they represent must be                 
  5877.  *       valid for the mode in which the EXEC is executed.                      
  5878.  *                                                                              
  5879.  * Note: Since the command can span input lines and the number of               
  5880.  *       arguments is variable, the arguments MUST be terminated                
  5881.  *       by a semicolon or end of file.                                         
  5882.  *                                                                              
  5883.  * Examples:  EXEC "time";                                                      
  5884.  *            EXEC "SE 'I have " UNREAD " new items' USER(JRL)";                
  5885.  *                                                                              
  5886.  *====================================================================*/        
  5887.                                                                                 
  5888. #pragma  csect(code,  "NN@BPEXE")                                               
  5889. #pragma  csect(static,"NN$BPEXE")                                               
  5890. #include "nn.h"                                                                 
  5891. #include "nnbatch.h"                                                            
  5892.                                                                                 
  5893. /****** Execute batch EXEC       command. ****************************/         
  5894.                                                                                 
  5895. static void                                                                     
  5896. NNMbxexe(np,bp,cmdp)                                                            
  5897. Rstruc nncb         *np;                                                        
  5898. Rstruc batch        *bp;                                                        
  5899. Rstruc newscmd      *cmdp;                                                      
  5900. {                                                                               
  5901.  char               *string;                                                    
  5902.  int                 rc;                                                        
  5903.                                                                                 
  5904.  string = NNMbbexp(np,bp,cmdp->cmd.mcmd.ptreep,STRING_SYMTYPE);                 
  5905.  if (bp->runtime_error) {                                                       
  5906.    fprintf(np->batch_outfile,                                                   
  5907.            "Command not executed due to errors building argument\n");           
  5908.  }                                                                              
  5909.  else {                                                                         
  5910.    fprintf(np->batch_outfile, "Executing command:\n%s\n\n", string);            
  5911.    rc = NNMtso(string);                                                         
  5912.    fprintf(np->batch_outfile, "\nReturn code: %d\n",rc);                        
  5913.  }                                                                              
  5914.                                                                                 
  5915.  return;                                                                        
  5916. }                                                                               
  5917.                                                                                 
  5918. /****** Parse batch EXEC         command. ****************************/         
  5919.                                                                                 
  5920. struct newscmd *                                                                
  5921. NNMbpexe(np,bp)                                                                 
  5922. Rstruc nncb         *np;                                                        
  5923. Rstruc batch        *bp;                                                        
  5924. {                                                                               
  5925.  struct newscmd     *cmdp       = NULL;                                         
  5926.  struct ptree       *treep      = NULL;                                         
  5927.                                                                                 
  5928.  treep = NNMbgexp(np,bp,STRING_SYMTYPE); /* Get data string struct */           
  5929.                                                                                 
  5930.  if (treep == NULL) {                                                           
  5931.    NNMbsynt(np,bp,NULL,0,"Error in arguments to EXEC");                         
  5932.    return NULL;                                                                 
  5933.  }                                                                              
  5934.                                                                                 
  5935.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for EXEC command");                  
  5936.                                                                                 
  5937.  if (cmdp) {                                                                    
  5938.    cmdp->mode = ANY_MODE;                                                       
  5939.    cmdp->proc = NNMbxexe;                                                       
  5940.    cmdp->cmd.mcmd.ptreep = treep;                                               
  5941.  }                                                                              
  5942.                                                                                 
  5943.  return cmdp;                                                                   
  5944. }                                                                               
  5945.                                                                                 
  5946. ./   ADD NAME=NNMBPEXT,SSI=010F0036                                             
  5947.                                                                                 
  5948.  /********************************************************************/         
  5949.  /*                                                                  */         
  5950.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  5951.  /*                                                                  */         
  5952.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  5953.  /* including the implied warranties of merchantability and fitness, */         
  5954.  /* are expressly denied.                                            */         
  5955.  /*                                                                  */         
  5956.  /* Provided this copyright notice is included, this software may    */         
  5957.  /* be freely distributed and not offered for sale.                  */         
  5958.  /*                                                                  */         
  5959.  /* Changes or modifications may be made and used only by the maker  */         
  5960.  /* of same, and not further distributed.  Such modifications should */         
  5961.  /* be mailed to the author for consideration for addition to the    */         
  5962.  /* software and incorporation in subsequent releases.               */         
  5963.  /*                                                                  */         
  5964.  /********************************************************************/         
  5965.                                                                                 
  5966. /*=====================================================================         
  5967.  *                                                                              
  5968.  * Command: EXTRACT                                                             
  5969.  *                                                                              
  5970.  * Syntax:  In per-newsgroup mode: EXTRACT ALL / READ / UNREAD                  
  5971.  *          In per-article   mode: EXTRACT                                      
  5972.  *                                                                              
  5973.  * Mode:    per-newsgroup or per-article                                        
  5974.  *                                                                              
  5975.  * Function: EXTRACTs all, read, or unread articles in the current              
  5976.  *           newsgroup; extracts the current article.                           
  5977.  *                                                                              
  5978.  * Note:     The file into which the article(s) are extracted is                
  5979.  *           specified by the contents of file DD:NNEXTTAB, which               
  5980.  *           is a listing of newsgroups and filenames.  The filenames           
  5981.  *           are expected to contain a wildcard asterisk, which is              
  5982.  *           substituted with the article number.                               
  5983.  *                                                                              
  5984.  * Examples:  EXTRACT                                                           
  5985.  *            EXTRACT ALL                                                       
  5986.  *            EXTRACT READ                                                      
  5987.  *            EXTRACT UNREAD                                                    
  5988.  *                                                                              
  5989.  *====================================================================*/        
  5990.                                                                                 
  5991. #pragma  csect(code,  "NN@BPEXT")                                               
  5992. #pragma  csect(static,"NN$BPEXT")                                               
  5993. #include "nn.h"                                                                 
  5994. #include "nnbatch.h"                                                            
  5995.                                                                                 
  5996. /*                                                                              
  5997.  * fine ARVEC             gp->article_vector[ap->number-1]                      
  5998.  * fine ARTICLE_IS_READ   (ARVEC == V_READ || ARVEC == V_MISSING_READ)          
  5999.  * fine ARTICLE_IS_UNREAD (ARVEC==V_UNREAD || ARVEC==V_MISSING_UNREAD)          
  6000.  */                                                                             
  6001.                                                                                 
  6002. #define ARTICLE_IS_UNREAD (V_STATUS(gp,ap->number) == V_UNREAD)                 
  6003. #define ARTICLE_IS_READ   (V_STATUS(gp,ap->number) != V_UNREAD)                 
  6004.                                                                                 
  6005. /********** Extract this article. ************************************/         
  6006.                                                                                 
  6007. static int                                                                      
  6008. extract_this_article(np,bp,gp,ap)                                               
  6009. Rstruc nncb            *np;                                                     
  6010. Rstruc batch           *bp;                                                     
  6011. Rstruc newsgroup       *gp;                                                     
  6012. Rstruc newsarticle     *ap;                                                     
  6013. {                                                                               
  6014.  FILE                  *xfp;                                                    
  6015.  char                  *cp1;                                                    
  6016.  char                  *cp2;                                                    
  6017.  char                   ddname  [9];                                            
  6018.  char                   exdsn  [81];                                            
  6019.  char                   expds  [81];                                            
  6020.  char                   member [81];                                            
  6021.  char                   thing_to_open [81];                                     
  6022.  Bool                   automark;                                               
  6023.                                                                                 
  6024.  *member = '\0';                                                                
  6025.  *ddname = '\0';                                                                
  6026.                                                                                 
  6027.  if (*bp->extractds_member) {                                                   
  6028.                                                                                 
  6029.    sprintf(member,"%8.8d",ap->number);                                          
  6030.    for (cp1=member,   cp2=bp->extractds_member;                                 
  6031.        *cp1=='0'  && *cp2;                                                      
  6032.         cp1++,        cp2++) {                                                  
  6033.      *cp1 = *cp2;                                                               
  6034.    }                                                                            
  6035.                                                                                 
  6036.    sprintf(exdsn, "%s%s%s", bp->extractds_part1, member,                        
  6037.                             bp->extractds_part2);                               
  6038.  }                                                                              
  6039.  else strcpy(exdsn,bp->extractds);                                              
  6040.                                                                                 
  6041.  automark = GETB("AUTOMARK");                                                   
  6042.                                                                                 
  6043.  np->extract_tab_expanding          = GETB("TABEXPAND");                        
  6044.  np->extract_appending              = bp->extractds_mode == PDS                 
  6045.                                       ? FALSE                                   
  6046.                                       : GETB("APPEND");                         
  6047.  np->extract_blank_before_separator = GETB("BLANKSEP");                         
  6048.  np->extract_separator_line         = GETC("SEPARATOR");                        
  6049.  np->extract_write_error            = FALSE;                                    
  6050.  np->extract_close_error            = FALSE;                                    
  6051.                                                                                 
  6052.  /* Preallocate the data set so that we don't run out of space                  
  6053.   * and so that brain-damaged C/370 doesn't barf on hyphens.                    
  6054.   * If it already exists, use the existing one.                                 
  6055.   */                                                                            
  6056.                                                                                 
  6057.  if (bp->extractds_mode == PDS) {                                               
  6058.                                                                                 
  6059.    strcpy(expds,exdsn);                                                         
  6060.    cp1 = strchr(expds,'(');                                                     
  6061.    *cp1 = '\0';                                                                 
  6062.    cp2 = strchr(cp1+1,')');                                                     
  6063.    *cp2 = '\0';                                                                 
  6064.                                                                                 
  6065.    strcpy(member,cp1+1);                                                        
  6066.                                                                                 
  6067.    if (!NNMalloc(expds,ddname,PDS,gp->real_article_count)) {                    
  6068.      fprintf(np->batch_outfile,                                                 
  6069.              "Could not allocate %s for extract.\n",expds);                     
  6070.      bp->runtime_error = TRUE;                                                  
  6071.      return 0;                                                                  
  6072.    }                                                                            
  6073.                                                                                 
  6074.    sprintf(thing_to_open, "dd:%s(%s)", ddname, member);                         
  6075.    sprintf(exdsn, "%s(%s)", expds, member);                                     
  6076.                                                                                 
  6077.  }                                                                              
  6078.  else {                                                                         
  6079.    if (!NNMalloc(exdsn,ddname,SEQ,gp->real_article_count)) {                    
  6080.      fprintf(np->batch_outfile,                                                 
  6081.              "Could not allocate %s for extract.\n",exdsn);                     
  6082.      bp->runtime_error = TRUE;                                                  
  6083.      return 0;                                                                  
  6084.    }                                                                            
  6085.                                                                                 
  6086.    sprintf(thing_to_open, "dd:%s", ddname);                                     
  6087.                                                                                 
  6088.  }                                                                              
  6089.                                                                                 
  6090.  xfp = OPEN_TEXT_FILE_FOR_WRITE_OR_APPEND(thing_to_open,                        
  6091.                                           np->extract_appending);               
  6092.                                                                                 
  6093.  if (!xfp) {                                                                    
  6094.    perror(exdsn);                                                               
  6095.    fprintf(np->batch_outfile,"Could not open %s for extract.\n",exdsn);         
  6096.    bp->runtime_error = TRUE;                                                    
  6097.    return 0;                                                                    
  6098.  }                                                                              
  6099.                                                                                 
  6100.  if (!NNMpick(np,ap)) {             /* Pick article */                          
  6101.    fprintf(np->batch_outfile,                                                   
  6102.            "Error accessing article %d of s.\n",ap->number,gp->name);           
  6103.    fprintf(np->batch_outfile,                                                   
  6104.            "Extraction into %s was not done.\n",exdsn);                         
  6105.  }                                                                              
  6106.  else {                                                                         
  6107.    NNMbtext(np,&ap->thdr,xfp);      /* Print text   */                          
  6108.  }                                                                              
  6109.                                                                                 
  6110.  if (fclose(xfp) < 0) {                                                         
  6111.    fprintf(np->batch_outfile,                                                   
  6112.            "Error closing %s.\n", exdsn);                                       
  6113.    bp->runtime_error = TRUE;                                                    
  6114.  }                                                                              
  6115.                                                                                 
  6116.  (void)NNMunalc(ddname);                                                        
  6117.                                                                                 
  6118.  if (bp->runtime_error ||                                                       
  6119.      np->extract_write_error || np->extract_close_error) {                      
  6120.    fprintf(np->batch_outfile,                                                   
  6121.            "Error extracting article %d of %s into %s.\n",                      
  6122.            ap->number, gp->name, exdsn);                                        
  6123.    bp->runtime_error = TRUE;                                                    
  6124.  }                                                                              
  6125.  else {                                                                         
  6126.    if (automark && ARTICLE_IS_UNREAD) {                                         
  6127.      NNMmarr(np,gp,ap);                                                         
  6128.      fprintf(np->batch_outfile,                                                 
  6129.              "Article %d of %s extracted into %s and marked read.\n",           
  6130.              ap->number, gp->name, exdsn);                                      
  6131.      NNMsave(np,NULL);   /* Checkpoint NEWSRC file */                           
  6132.    }                                                                            
  6133.    else {                                                                       
  6134.      fprintf(np->batch_outfile,                                                 
  6135.              "Article %d of %s extracted into %s.\n",                           
  6136.              ap->number, gp->name, exdsn);                                      
  6137.    }                                                                            
  6138.  }                                                                              
  6139.                                                                                 
  6140.  return (bp->runtime_error ? 0 : 1);                                            
  6141. }                                                                               
  6142.                                                                                 
  6143. /********** Extract articles. ****************************************/         
  6144.                                                                                 
  6145. static int                                                                      
  6146. extract_articles(np,bp,gp,extracting)                                           
  6147. Rstruc nncb            *np;                                                     
  6148. Rstruc batch           *bp;                                                     
  6149. Rstruc newsgroup       *gp;                                                     
  6150. enum extracting_mode    extracting;                                             
  6151. {                                                                               
  6152.  Rstruc newsarticle    *ap;                                                     
  6153.  Rstruc newsgroup      *gp1;                                                    
  6154.  int                    count = 0;                                              
  6155.                                                                                 
  6156.  /* code copied from NNMbxfar and by extension from NNMpng */                   
  6157.                                                                                 
  6158.  np->current_newsgroup   = gp;                                                  
  6159.  np->newsgroup_selected  = FALSE;                                               
  6160.                                                                                 
  6161.  np->newsgroup_not_found = FALSE;                                               
  6162.                                                                                 
  6163.  if (gp->first_article == NULL) gp1 = do_newsgroup_by_address(np,gp);           
  6164.  else                           gp1 = gp;                                       
  6165.                                                                                 
  6166.  if (np->newsgroup_not_found) {                                                 
  6167.    SetNoSuchGroup(gp);                                                          
  6168.    gp->real_article_count = 0;                                                  
  6169.    gp->real_unread_count  = 0;                                                  
  6170.  }                                                                              
  6171.  else if (gp1) {                                                                
  6172.    bp->gp = gp1;                                                                
  6173.    gp = gp1;                                                                    
  6174.                                                                                 
  6175.    if (NNMraarh(np,gp)) {            /* Retrieve all article headers*/          
  6176.                                                                                 
  6177.      if (gp->first_article) {                                                   
  6178.                                                                                 
  6179.        /* first loop is to make sure the articles are all there */              
  6180.                                                                                 
  6181.        ap = gp->first_article;                                                  
  6182.        while (ap <= gp->real_last_article) {                                    
  6183.          if (ap->number != NO_VALUE) {                                          
  6184.            if ((extracting == EXTRACTING_ALL)                                   
  6185.             || (extracting == EXTRACTING_READ && ARTICLE_IS_READ)               
  6186.             || (extracting == EXTRACTING_UNREAD && ARTICLE_IS_UNREAD)) {        
  6187.              NNMrarh(np,gp,ap,TRUE,NULL); /* Retrieve article header */         
  6188.              if (np->article_error_found) {                                     
  6189.                ap = gp->first_article;                                          
  6190.                continue;                                                        
  6191.              }                                                                  
  6192.            }                                                                    
  6193.          }                                                                      
  6194.          ap++;                                                                  
  6195.        }                                                                        
  6196.                                                                                 
  6197.        /* second loop is to actually process the articles */                    
  6198.                                                                                 
  6199.        for (ap = gp->first_article; ap <= gp->fake_last_article; ap++) {        
  6200.          if (ap->number == NO_VALUE) continue;                                  
  6201.          if ((extracting == EXTRACTING_ALL)                                     
  6202.           || (extracting == EXTRACTING_READ && ARTICLE_IS_READ)                 
  6203.           || (extracting == EXTRACTING_UNREAD && ARTICLE_IS_UNREAD)) {          
  6204.            count += extract_this_article(np,bp,gp,ap);                          
  6205.          }                                                                      
  6206.        }                                                                        
  6207.      }                                                                          
  6208.    }                                                                            
  6209.  }                                                                              
  6210.                                                                                 
  6211.  return count;                                                                  
  6212. }                                                                               
  6213.                                                                                 
  6214. /********** Get extract file. ****************************************/         
  6215.                                                                                 
  6216. static Bool                                                                     
  6217. get_extract_file(np,bp,gp)                                                      
  6218. Rstruc nncb            *np;                                                     
  6219. Rstruc batch           *bp;                                                     
  6220. Rstruc newsgroup       *gp;                                                     
  6221. {                                                                               
  6222.  FILE                  *tabfp;                                                  
  6223.  char                  *asp;                                                    
  6224.  char                  *cp;                                                     
  6225.  char                  *cp1;                                                    
  6226.  char                  *cp2;                                                    
  6227.  char                  *lp;                                                     
  6228.  char                  *rp;                                                     
  6229.  int                    len;                                                    
  6230.  enum data_set_type     mode;                                                   
  6231.  Bool                   found_extract;                                          
  6232.  char                   line    [260];                                          
  6233.  char                   tabname [260];                                          
  6234.  char                   tabds   [260];                                          
  6235.                                                                                 
  6236.  strcpy(bp->extractds,"");                                                      
  6237.                                                                                 
  6238.  /* Open the extract table. */                                                  
  6239.                                                                                 
  6240.  if (!(tabfp = fopen("DD:NNEXTTAB","r"))) {                                     
  6241.    perror("extract table (ddname NNEXTTAB)");                                   
  6242.    fprintf(np->batch_outfile,"Could not open extract table.\n");                
  6243.    bp->runtime_error = TRUE;                                                    
  6244.    return FALSE;                                                                
  6245.  }                                                                              
  6246.                                                                                 
  6247.  /* Search the extract table for a line that matches this newsgroup. */         
  6248.                                                                                 
  6249.  found_extract = FALSE;                                                         
  6250.                                                                                 
  6251.  do {                                                                           
  6252.    fgets(line, sizeof line, tabfp);                                             
  6253.    if (feof(tabfp)) break;                                                      
  6254.    if (ferror(tabfp)) {                                                         
  6255.      fprintf(np->batch_outfile,                                                 
  6256.              "Error reading extract table (ddname NNEXTTAB)");                  
  6257.      break;                                                                     
  6258.    }                                                                            
  6259.    strcpy(tabname,"");                                                          
  6260.    strcpy(tabds  ,"");                                                          
  6261.    sscanf(line,"%s %s",tabname, tabds);                                         
  6262.    if (!*tabname) continue;                                                     
  6263.    for (cp = tabname; *cp; cp++) *cp = tolower(*cp);                            
  6264.    if (UNEQUAL(tabname, gp->name)) continue;                                    
  6265.    found_extract = TRUE;                                                        
  6266.    if (!*tabds) {                                                               
  6267.      fprintf(np->batch_outfile,                                                 
  6268.      "Extract table entry for group %s has no file name specified.\n",          
  6269.              gp->name);                                                         
  6270.      break;                                                                     
  6271.    }                                                                            
  6272.  } while (!found_extract);                                                      
  6273.                                                                                 
  6274.  if (!found_extract) {                                                          
  6275.    fprintf(np->batch_outfile,                                                   
  6276.     "Extract terminated for group %s, no entry in extract table.\n",            
  6277.      gp->name);                                                                 
  6278.    return FALSE;                                                                
  6279.  }                                                                              
  6280.                                                                                 
  6281.  if (fclose(tabfp) < 0) {                                                       
  6282.    fprintf(stderr,"Error closing extract table (ddname NNEXTTAB)");             
  6283.    fprintf(np->batch_outfile,"Could not close extract table\n");                
  6284.    bp->runtime_error = TRUE;                                                    
  6285.    return FALSE;                                                                
  6286.  }                                                                              
  6287.                                                                                 
  6288.  if (*tabds == '!') {                                                           
  6289.    fprintf(np->batch_outfile,                                                   
  6290.            "Extract suppressed for group %s ('!' in extract table).\n",         
  6291.            gp->name);                                                           
  6292.    return FALSE;                                                                
  6293.  }                                                                              
  6294.                                                                                 
  6295.  /* Copy table dsn to extract dsn, upcasing and stripping all quotes */         
  6296.                                                                                 
  6297.  for (cp1 = tabds, cp2 = bp->extractds; *cp1; cp1++) {                          
  6298.    if (*cp1 != '\'') *cp2++ = toupper(*cp1);                                    
  6299.  }                                                                              
  6300.  *cp2 = '\0';                                                                   
  6301.                                                                                 
  6302.  lp  = strchr(bp->extractds,'(');                                               
  6303.  rp  = strchr(bp->extractds,')');                                               
  6304.  asp = strchr(bp->extractds,'*');                                               
  6305.                                                                                 
  6306.  if (lp && rp) {                                                                
  6307.    if (*(rp+1) != '\0') {                                                       
  6308.      fprintf(np->batch_outfile,                                                 
  6309.              "Misuse of parentheses in extract file template %s\n",             
  6310.              bp->extractds);                                                    
  6311.      bp->runtime_error = TRUE;                                                  
  6312.      return FALSE;                                                              
  6313.    }                                                                            
  6314.    if (!asp) {                                                                  
  6315.      fprintf(np->batch_outfile,                                                 
  6316.              "Parentheses without '*' in extract file template %s\n",           
  6317.              bp->extractds);                                                    
  6318.      fprintf(np->batch_outfile,                                                 
  6319.              "(cannot append multiple articles to same PDS member)\n");         
  6320.      bp->runtime_error = TRUE;                                                  
  6321.      return FALSE;                                                              
  6322.    }                                                                            
  6323.    mode = PDS;                                                                  
  6324.  }                                                                              
  6325.  else {                                                                         
  6326.    if (lp || rp) {                                                              
  6327.      fprintf(np->batch_outfile,                                                 
  6328.              "Misuse of parentheses in extract file template %s\n",             
  6329.              bp->extractds);                                                    
  6330.      bp->runtime_error = TRUE;                                                  
  6331.      return FALSE;                                                              
  6332.    }                                                                            
  6333.    mode = SEQ;                                                                  
  6334.  }                                                                              
  6335.                                                                                 
  6336.  if (strchr(asp+1,'*')) {                                                       
  6337.    fprintf(np->batch_outfile,                                                   
  6338.            "Too many '*' in extract file template %s\n",                        
  6339.            bp->extractds);                                                      
  6340.    bp->runtime_error = TRUE;                                                    
  6341.    return FALSE;                                                                
  6342.  }                                                                              
  6343.                                                                                 
  6344.  if (asp) {                                                                     
  6345.    switch (*(asp+1)) {                                                          
  6346.      case '\0':                                                                 
  6347.      case ')':                                                                  
  6348.      case '(':                                                                  
  6349.      case '.':  break;                                                          
  6350.      default:                                                                   
  6351.             fprintf(np->batch_outfile,                                          
  6352.                     "Invalid use of '*' in extract file template %s\n",         
  6353.                     bp->extractds);                                             
  6354.             fprintf(np->batch_outfile,                                          
  6355.                     "(must be followed by '.', ')' or end of name)\n");         
  6356.             bp->runtime_error = TRUE;                                           
  6357.             return FALSE;                                                       
  6358.    }                                                                            
  6359.    for (cp = asp-1;                                                             
  6360.         cp >= bp->extractds && (*cp != '(' && *cp != '.');                      
  6361.         cp--);                                                                  
  6362.    cp++;                                                                        
  6363.    if (cp == asp) {                                                             
  6364.      fprintf(np->batch_outfile,                                                 
  6365.              "Invalid use of '*' in extract file template %s\n",                
  6366.              bp->extractds);                                                    
  6367.      fprintf(np->batch_outfile,                                                 
  6368.              "(must be preceded by an alphanumeric dsname char)\n");            
  6369.      bp->runtime_error = TRUE;                                                  
  6370.      return FALSE;                                                              
  6371.    }                                                                            
  6372.    len = cp - bp->extractds;                                                    
  6373.    memcpy(bp->extractds_part1,  bp->extractds, len);                            
  6374.    *(bp->extractds_part1 + len) = '\0';                                         
  6375.    len = asp - cp;                                                              
  6376.    memcpy(bp->extractds_member, cp, len);                                       
  6377.    *(bp->extractds_member + len) = '\0';                                        
  6378.    strcpy(bp->extractds_part2,  asp+1);                                         
  6379.  }                                                                              
  6380.  else {                                                                         
  6381.    strcpy(bp->extractds_part1, bp->extractds);                                  
  6382.    strcpy(bp->extractds_part2, "");                                             
  6383.    strcpy(bp->extractds_member,"");                                             
  6384.  }                                                                              
  6385.                                                                                 
  6386.  bp->extractds_mode = mode;                                                     
  6387.                                                                                 
  6388.  return TRUE;                                                                   
  6389. }                                                                               
  6390.                                                                                 
  6391. /********** Execute batch EXTRACT command. ***************************/         
  6392.                                                                                 
  6393. static void                                                                     
  6394. NNMbxext(np,bp,cmdp)                                                            
  6395. Rstruc nncb            *np;                                                     
  6396. Rstruc batch           *bp;                                                     
  6397. Rstruc newscmd         *cmdp;                                                   
  6398. {                                                                               
  6399.  struct newsgroup      *gp    = bp->gp;                                         
  6400.  int                    count = 0;                                              
  6401.  enum extracting_mode   extracting;                                             
  6402.                                                                                 
  6403.  extracting = cmdp->cmd.xcmd.extracting;                                        
  6404.                                                                                 
  6405.  if (get_extract_file(np,bp,gp)) {                                              
  6406.    if (extracting == NO_EXTRACTING_MODE) {                                      
  6407.      count = extract_this_article(np,bp,gp,bp->ap);                             
  6408.    }                                                                            
  6409.    else {                                                                       
  6410.      count = extract_articles(np,bp,gp,extracting);                             
  6411.    }                                                                            
  6412.  }                                                                              
  6413.  if (bp->runtime_error) {                                                       
  6414.    fprintf(np->batch_outfile, "Extraction failed for %s.\n",                    
  6415.                               gp->name);                                        
  6416.  }                                                                              
  6417.  else {                                                                         
  6418.    fprintf(np->batch_outfile, "%d article%s extracted for %s.\n",               
  6419.                               count, count==1 ? "" : "s", gp->name);            
  6420.  }                                                                              
  6421.                                                                                 
  6422.  return;                                                                        
  6423.                                                                                 
  6424. }                                                                               
  6425.                                                                                 
  6426. /****** Per-newsgroup mode EXTRACT. **********************************/         
  6427.                                                                                 
  6428. static struct newscmd *                                                         
  6429. parse_newsgroup_extract(np,bp)                                                  
  6430. Rstruc nncb            *np;                                                     
  6431. Rstruc batch           *bp;                                                     
  6432. {                                                                               
  6433.  struct newscmd        *cmdp       = NULL;                                      
  6434.  enum extracting_mode   extracting = NO_EXTRACTING_MODE;                        
  6435.                                                                                 
  6436.  /*                                                                             
  6437.   * Next token must be ALL, READ or UNREAD.                                     
  6438.   */                                                                            
  6439.                                                                                 
  6440.  if (NNMbgtok(np,bp,TOKEN_READ)) {  /* get token */                             
  6441.    switch (bp->curtok.type) {                                                   
  6442.      case WORD_TOKEN:                                                           
  6443.                       if (EQUAL(bp->curtok.string,"ALL")) {                     
  6444.                         extracting = EXTRACTING_ALL;                            
  6445.                       }                                                         
  6446.                       if (EQUAL(bp->curtok.string,"READ")) {                    
  6447.                         extracting = EXTRACTING_READ;                           
  6448.                       }                                                         
  6449.                       else if (EQUAL(bp->curtok.string,"UNREAD")) {             
  6450.                         extracting = EXTRACTING_UNREAD;                         
  6451.                       }                                                         
  6452.                       break;                                                    
  6453.      default:                                                                   
  6454.                       break;                                                    
  6455.    }                                                                            
  6456.  }                                                                              
  6457.                                                                                 
  6458.  if (extracting == NO_EXTRACTING_MODE) {                                        
  6459.    NNMbsynt(np,bp,bp->curtok.string,0,                                          
  6460.          "EXTRACT in per-newsgroup mode requires ALL, READ or UNREAD");         
  6461.  }                                                                              
  6462.                                                                                 
  6463.  bp->stop_at_newline = TRUE;                                                    
  6464.                                                                                 
  6465.  NNMbtras(np,bp,"EXTRACT"); /* Trash extraneous parameters */                   
  6466.                                                                                 
  6467.  if (bp->syntax_error) return NULL;                                             
  6468.                                                                                 
  6469.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for EXTRACT command");               
  6470.                                                                                 
  6471.  if (cmdp) {                                                                    
  6472.    cmdp->mode = PER_NEWSGROUP_MODE;                                             
  6473.    cmdp->proc = NNMbxext;                                                       
  6474.    cmdp->cmd.xcmd.extracting = extracting;                                      
  6475.  }                                                                              
  6476.                                                                                 
  6477.  return cmdp;                                                                   
  6478. }                                                                               
  6479.                                                                                 
  6480. /****** Per-article mode EXTRACT. ************************************/         
  6481.                                                                                 
  6482. static struct newscmd *                                                         
  6483. parse_article_extract(np,bp)                                                    
  6484. Rstruc nncb            *np;                                                     
  6485. Rstruc batch           *bp;                                                     
  6486. {                                                                               
  6487.  struct newscmd        *cmdp       = NULL;                                      
  6488.  bp->stop_at_newline = TRUE;                                                    
  6489.                                                                                 
  6490.  NNMbtras(np,bp,"EXTRACT"); /* Trash extraneous parameters */                   
  6491.                                                                                 
  6492.  if (bp->syntax_error) return NULL;                                             
  6493.                                                                                 
  6494.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for EXTRACT command");               
  6495.                                                                                 
  6496.  if (cmdp) {                                                                    
  6497.    cmdp->mode = PER_ARTICLE_MODE;                                               
  6498.    cmdp->proc = NNMbxext;                                                       
  6499.    cmdp->cmd.xcmd.extracting = NO_EXTRACTING_MODE;                              
  6500.  }                                                                              
  6501.                                                                                 
  6502.  return cmdp;                                                                   
  6503. }                                                                               
  6504.                                                                                 
  6505. /****** Parse batch EXTRACT      command. ****************************/         
  6506.                                                                                 
  6507. struct newscmd *                                                                
  6508. NNMbpext(np,bp)                                                                 
  6509. Rstruc nncb         *np;                                                        
  6510. Rstruc batch        *bp;                                                        
  6511. {                                                                               
  6512.                                                                                 
  6513.  switch (bp->mode) {                                                            
  6514.    case PER_NEWSGROUP_MODE: return parse_newsgroup_extract (np,bp);             
  6515.    case PER_ARTICLE_MODE:   return parse_article_extract   (np,bp);             
  6516.    default:                                                                     
  6517.         NNMbsynt(np,bp,NULL,0,                                                  
  6518.         "EXTRACT belongs in per-newsgroup mode or per-article mode");           
  6519.    return NULL;                                                                 
  6520.  }                                                                              
  6521.                                                                                 
  6522. }                                                                               
  6523.                                                                                 
  6524. ./   ADD NAME=NNMBPFOR,SSI=01190038                                             
  6525.                                                                                 
  6526.  /********************************************************************/         
  6527.  /*                                                                  */         
  6528.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6529.  /*                                                                  */         
  6530.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6531.  /* including the implied warranties of merchantability and fitness, */         
  6532.  /* are expressly denied.                                            */         
  6533.  /*                                                                  */         
  6534.  /* Provided this copyright notice is included, this software may    */         
  6535.  /* be freely distributed and not offered for sale.                  */         
  6536.  /*                                                                  */         
  6537.  /* Changes or modifications may be made and used only by the maker  */         
  6538.  /* of same, and not further distributed.  Such modifications should */         
  6539.  /* be mailed to the author for consideration for addition to the    */         
  6540.  /* software and incorporation in subsequent releases.               */         
  6541.  /*                                                                  */         
  6542.  /********************************************************************/         
  6543.                                                                                 
  6544. /*=====================================================================         
  6545.  *                                                                              
  6546.  * Command: FOR                                                                 
  6547.  *                                                                              
  6548.  * Syntax:  (1) in top-level mode...                                            
  6549.  *                                                                              
  6550.  *          FOR criterion {WHEN filter} DO;                                     
  6551.  *          command(s);                                                         
  6552.  *          END;                                                                
  6553.  *                                                                              
  6554.  *          where                                                               
  6555.  *                                                                              
  6556.  *          criterion is one of: ALL                                            
  6557.  *                               REGISTERED                                     
  6558.  *                               UNREGISTERED                                   
  6559.  *                               "groupmask"  (e.g. "comp*")                    
  6560.  *                               {NEWS}GROUP{S} "groupnames"                    
  6561.  *                                                                              
  6562.  *          filter is any flag expression                                       
  6563.  *                                                                              
  6564.  *          commands are any commands for the appropriate mode                  
  6565.  *                                                                              
  6566.  * Examples:                                                                    
  6567.  *                                                                              
  6568.  *   FOR ALL                  DO ... { per-newsgroup commands }                 
  6569.  *   FOR REGISTERED           DO ...                                            
  6570.  *   FOR "comp.*"             DO ...                                            
  6571.  *   FOR GROUPS "a.b.c d.e.f" DO ...                                            
  6572.  *   FOR NEWSGROUP "a.b.c" DO ...                                               
  6573.  *   FOR ... WHEN (READ = nn) DO ...                                            
  6574.  *   FOR ... WHEN (UNREAD > nn) DO ...                                          
  6575.  *   FOR ... WHEN (COUNT < nn) DO ...                                           
  6576.  *                                                                              
  6577.  * Syntax:  (2) in per-newsgroup mode...                                        
  6578.  *                                                                              
  6579.  *          FOR criterion {WHEN filter} DO;                                     
  6580.  *          command(s);                                                         
  6581.  *          END;                                                                
  6582.  *                                                                              
  6583.  *          where                                                               
  6584.  *                                                                              
  6585.  *          criterion is one of: ALL                                            
  6586.  *                               READ                                           
  6587.  *                               UNREAD                                         
  6588.  *                               i TO j  (i = number or FIRST,                  
  6589.  *                                       (j = number or LAST)                   
  6590.  *                                                                              
  6591.  *          filter is any flag expression                                       
  6592.  *                                                                              
  6593.  *          commands are any commands for the appropriate mode                  
  6594.  *                                                                              
  6595.  * Examples:                                                                    
  6596.  *                                                                              
  6597.  * FOR ALL WHEN "foo" IN SUBJECT DO ...                                         
  6598.  * FOR UNREAD DO ...                                                            
  6599.  * FOR FIRST TO 10 DO ...                                                       
  6600.  *                                                                              
  6601.  * Mode:    (1) top-level     (picking newsgroups)                              
  6602.  *          (2) per-newsgroup (picking articles)                                
  6603.  *                                                                              
  6604.  * For (1), the commands between DO and END are in per-newsgroup mode.          
  6605.  * For (2), the commands between DO and END are in per-article mode.            
  6606.  *                                                                              
  6607.  * Function: Defines operations to be performed on each newsgroup               
  6608.  *           in a list of newsgroups (1), or on each article in a               
  6609.  *           list of articles (2).                                              
  6610.  *                                                                              
  6611.  *                                                                              
  6612.  *====================================================================*/        
  6613.                                                                                 
  6614. #pragma  csect(code,  "NN@BPFOR")                                               
  6615. #pragma  csect(static,"NN$BPFOR")                                               
  6616. #include "nn.h"                                                                 
  6617. #include "nnbatch.h"                                                            
  6618.                                                                                 
  6619. /****** Get keyword. *************************************************/         
  6620.                                                                                 
  6621. static Bool                                                                     
  6622. get_keyword(np,bp,key)                                                          
  6623. Rstruc nncb                 *np;                                                
  6624. Rstruc batch                *bp;                                                
  6625. char                        *key;                                               
  6626. {                                                                               
  6627.  struct token               *tp;                                                
  6628.                                                                                 
  6629.  if ((tp = PEEK())                                                              
  6630.   && tp->type == WORD_TOKEN                                                     
  6631.   && EQUAL(tp->string,key)) {                                                   
  6632.    EAT();                                                                       
  6633.    return TRUE;                                                                 
  6634.  }                                                                              
  6635.                                                                                 
  6636.  else return FALSE;                                                             
  6637.                                                                                 
  6638. }                                                                               
  6639.                                                                                 
  6640. /****** Parse initial-mode FOR for newsgroups. ***********************/         
  6641.                                                                                 
  6642. static struct newscmd *                                                         
  6643. parse_for_newsgroups(np,bp)                                                     
  6644. Rstruc nncb                 *np;                                                
  6645. Rstruc batch                *bp;                                                
  6646. {                                                                               
  6647.  struct token               *tp;                                                
  6648.  struct newscmd             *cmdp       = NULL;                                 
  6649.  struct ptree               *filter     = NULL;                                 
  6650.  struct cmdtree             *treep      = NULL;                                 
  6651.  struct ptree               *groups     = NULL;                                 
  6652.  enum which_newsgroups       which      = NO_NEWSGROUPS;                        
  6653.                                                                                 
  6654.  /* Look for criterion, one of:                                                 
  6655.   *                              ALL                                            
  6656.   *                              REGISTERED                                     
  6657.   *                              UNREGISTERED                                   
  6658.   *                              GROUPMASK group-mask-expression                
  6659.   *                              {NEWS}GROUP{S} group-name-expression           
  6660.   */                                                                            
  6661.                                                                                 
  6662.  if ((tp = PEEK())) {                                                           
  6663.    switch (tp->type) {                                                          
  6664.      case WORD_TOKEN:                                                           
  6665.                          if      (EQUAL(tp->string,"ALL")) {                    
  6666.                            EAT();                                               
  6667.                            which = ALL_NEWSGROUPS;                              
  6668.                          }                                                      
  6669.                          else if (EQUAL(tp->string,"REGISTERED")) {             
  6670.                            EAT();                                               
  6671.                            which = REGISTERED_NEWSGROUPS;                       
  6672.                          }                                                      
  6673.                          else if (EQUAL(tp->string,"UNREGISTERED")) {           
  6674.                            EAT();                                               
  6675.                            which = UNREGISTERED_NEWSGROUPS;                     
  6676.                          }                                                      
  6677.                          else if (EQUAL(tp->string,"GROUP")                     
  6678.                                || EQUAL(tp->string,"GROUPS")                    
  6679.                                || EQUAL(tp->string,"NEWSGROUP")                 
  6680.                                || EQUAL(tp->string,"NEWSGROUPS")) {             
  6681.                            EAT();                                               
  6682.                            which = NAMED_NEWSGROUPS;                            
  6683.                          }                                                      
  6684.                          else if (EQUAL(tp->string,"GROUPMASK")                 
  6685.                                || EQUAL(tp->string,"NEWSGROUPMASK")) {          
  6686.                            EAT();                                               
  6687.                            which = MASKED_NEWSGROUPS;                           
  6688.                          }                                                      
  6689.                          break;                                                 
  6690.      case STRING_TOKEN:  which = MASKED_NEWSGROUPS;                             
  6691.                          break;                                                 
  6692.      default:                                                                   
  6693.                          break;                                                 
  6694.    }                                                                            
  6695.  }                                                                              
  6696.                                                                                 
  6697.  switch (which) {                                                               
  6698.    case NO_NEWSGROUPS:                                                          
  6699.                            NNMbsynt(np,bp,NULL,0,                               
  6700.   "Missing FOR criterion - ALL, REGISTERED, UNREGISTERED, NEWSGROUPS"           
  6701.                                  );                                             
  6702.                            break;                                               
  6703.    case NAMED_NEWSGROUPS:                                                       
  6704.                            groups = NNMbgexp(np,bp,STRING_SYMTYPE);             
  6705.                            if (!groups) {                                       
  6706.                              NNMbsynt(np,bp,NULL,0,                             
  6707.                                       "No valid group list specified");         
  6708.                            }                                                    
  6709.                            break;                                               
  6710.    case MASKED_NEWSGROUPS:                                                      
  6711.                            groups = NNMbgexp(np,bp,STRING_SYMTYPE);             
  6712.                            if (!groups) {                                       
  6713.                              NNMbsynt(np,bp,NULL,0,                             
  6714.                                       "No valid group mask specified");         
  6715.                            }                                                    
  6716.                            break;                                               
  6717.    default: break;                                                              
  6718.  }                                                                              
  6719.                                                                                 
  6720.  /* Look for WHEN.  If found, then look for filter, a flag expression.          
  6721.   */                                                                            
  6722.                                                                                 
  6723.  if (get_keyword(np,bp,"WHEN")) {                                               
  6724.    filter = NNMbgexp(np,bp,FLAG_SYMTYPE);                                       
  6725.    if (!filter) {                                                               
  6726.      NNMbsynt(np,bp,NULL,0,"No valid filter expression specified");             
  6727.    }                                                                            
  6728.  }                                                                              
  6729.                                                                                 
  6730.  /* Get DO-END command group.  */                                               
  6731.                                                                                 
  6732.  treep = NNMbgdo(np,bp,PER_NEWSGROUP_MODE);                                     
  6733.                                                                                 
  6734.  if (bp->syntax_error) return NULL;                                             
  6735.                                                                                 
  6736.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for FOR command");                   
  6737.                                                                                 
  6738.  if (cmdp) {                                                                    
  6739.    cmdp->mode = INITIAL_MODE;                                                   
  6740.    cmdp->proc = NNMbxfng;                                                       
  6741.    cmdp->cmd.icmd.fors.filter          = filter;                                
  6742.    cmdp->cmd.icmd.fors.treep           = treep;                                 
  6743.    cmdp->cmd.icmd.fors.crit.which      = which;                                 
  6744.    cmdp->cmd.icmd.fors.crit.groups     = groups;                                
  6745.  }                                                                              
  6746.                                                                                 
  6747.  return cmdp;                                                                   
  6748.                                                                                 
  6749. }                                                                               
  6750.                                                                                 
  6751. /****** Parse per-newsgroup-mode FOR for articles. *******************/         
  6752.                                                                                 
  6753. static struct newscmd *                                                         
  6754. parse_for_articles(np,bp)                                                       
  6755. Rstruc nncb                 *np;                                                
  6756. Rstruc batch                *bp;                                                
  6757. {                                                                               
  6758.  struct token               *tp;                                                
  6759.  struct newscmd             *cmdp        = NULL;                                
  6760.  struct ptree               *filter      = NULL;                                
  6761.  struct cmdtree             *treep       = NULL;                                
  6762.  struct ptree               *first       = NULL;                                
  6763.  struct ptree               *last        = NULL;                                
  6764.  enum which_articles         which       = NO_ARTICLES;                         
  6765.                                                                                 
  6766.  /* Look for criterion, one of:                                                 
  6767.   *                              ALL                                            
  6768.   *                              READ                                           
  6769.   *                              UNREAD                                         
  6770.   *                              i/FIRST to j/LAST                              
  6771.   *                                                                             
  6772.   * Note: FIRST and LAST will be variables at run time, making it               
  6773.   *       easier to handle them.  That way you can say things like              
  6774.   *       FIRST + 1 TO LAST - 3.                                                
  6775.   */                                                                            
  6776.                                                                                 
  6777.  if ((tp = PEEK())) {                                                           
  6778.    switch (tp->type) {                                                          
  6779.      case WORD_TOKEN:                                                           
  6780.                          if      (EQUAL(tp->string,"ALL")) {                    
  6781.                            EAT();                                               
  6782.                            which = ALL_ARTICLES;                                
  6783.                          }                                                      
  6784.                          else if (EQUAL(tp->string,"READ")) {                   
  6785.                            EAT();                                               
  6786.                            which = READ_ARTICLES;                               
  6787.                          }                                                      
  6788.                          else if (EQUAL(tp->string,"UNREAD")) {                 
  6789.                            EAT();                                               
  6790.                            which = UNREAD_ARTICLES;                             
  6791.                          }                                                      
  6792.                          else which = RANGED_ARTICLES;                          
  6793.                          break;                                                 
  6794.      default:            which = RANGED_ARTICLES;                               
  6795.                          break;                                                 
  6796.    }                                                                            
  6797.  }                                                                              
  6798.                                                                                 
  6799.  switch (which) {                                                               
  6800.    case NO_ARTICLES:                                                            
  6801.                          NNMbsynt(np,bp,NULL,0,                                 
  6802.   "Missing FOR criterion - ALL, READ, UNREAD, or n/FIRST to n/LAST"             
  6803.                                );                                               
  6804.                          break;                                                 
  6805.    case RANGED_ARTICLES:                                                        
  6806.                          first = NNMbgexp(np,bp,NUMBER_SYMTYPE);                
  6807.                          if (!first) {                                          
  6808.                            NNMbsynt(np,bp,NULL,0,                               
  6809.                                   "No valid range start given");                
  6810.                          }                                                      
  6811.                          if (get_keyword(np,bp,"TO")) {                         
  6812.                            last = NNMbgexp(np,bp,NUMBER_SYMTYPE);               
  6813.                            if (!last) {                                         
  6814.                              NNMbsynt(np,bp,NULL,0,                             
  6815.                                      "No valid range end given");               
  6816.                            }                                                    
  6817.                          }                                                      
  6818.                          else {                                                 
  6819.                            last = NULL;                                         
  6820.                          }                                                      
  6821.                          break;                                                 
  6822.    default: break;                                                              
  6823.  }                                                                              
  6824.                                                                                 
  6825.  /* Look for WHEN.  If found, then look for filter, a flag expression.          
  6826.   */                                                                            
  6827.                                                                                 
  6828.  if (get_keyword(np,bp,"WHEN")) {                                               
  6829.    filter = NNMbgexp(np,bp,FLAG_SYMTYPE);                                       
  6830.    if (!filter) {                                                               
  6831.      NNMbsynt(np,bp,NULL,0,"No valid filter expression specified");             
  6832.    }                                                                            
  6833.  }                                                                              
  6834.                                                                                 
  6835.  /* Get DO-END command group.  */                                               
  6836.                                                                                 
  6837.  treep = NNMbgdo(np,bp,PER_ARTICLE_MODE);                                       
  6838.                                                                                 
  6839.  if (bp->syntax_error) return NULL;                                             
  6840.                                                                                 
  6841.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for FOR command");                   
  6842.                                                                                 
  6843.  if (cmdp) {                                                                    
  6844.    cmdp->mode = PER_NEWSGROUP_MODE;                                             
  6845.    cmdp->proc = NNMbxfar;                                                       
  6846.    cmdp->cmd.ncmd.fors.filter     = filter;                                     
  6847.    cmdp->cmd.ncmd.fors.treep      = treep;                                      
  6848.    cmdp->cmd.ncmd.fors.crit.which = which;                                      
  6849.    cmdp->cmd.ncmd.fors.crit.first = first;                                      
  6850.    cmdp->cmd.ncmd.fors.crit.last  = last;                                       
  6851.  }                                                                              
  6852.                                                                                 
  6853.  return cmdp;                                                                   
  6854.                                                                                 
  6855. }                                                                               
  6856.                                                                                 
  6857. /****** Parse batch FOR          command. ****************************/         
  6858.                                                                                 
  6859. struct newscmd *                                                                
  6860. NNMbpfor(np,bp)                                                                 
  6861. Rstruc nncb         *np;                                                        
  6862. Rstruc batch        *bp;                                                        
  6863. {                                                                               
  6864.                                                                                 
  6865.  switch (bp->mode) {                                                            
  6866.    case INITIAL_MODE:       return parse_for_newsgroups(np,bp);                 
  6867.    case PER_NEWSGROUP_MODE: return parse_for_articles  (np,bp);                 
  6868.    default:                                                                     
  6869.             NNMbsynt(np,bp,NULL,0,                                              
  6870.             "FOR belongs in initial mode or per-newsgroup mode");               
  6871.    return NULL;                                                                 
  6872.  }                                                                              
  6873.                                                                                 
  6874. }                                                                               
  6875.                                                                                 
  6876. ./   ADD NAME=NNMBPHEL,SSI=010C0056                                             
  6877.                                                                                 
  6878.  /********************************************************************/         
  6879.  /*                                                                  */         
  6880.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6881.  /*                                                                  */         
  6882.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6883.  /* including the implied warranties of merchantability and fitness, */         
  6884.  /* are expressly denied.                                            */         
  6885.  /*                                                                  */         
  6886.  /* Provided this copyright notice is included, this software may    */         
  6887.  /* be freely distributed and not offered for sale.                  */         
  6888.  /*                                                                  */         
  6889.  /* Changes or modifications may be made and used only by the maker  */         
  6890.  /* of same, and not further distributed.  Such modifications should */         
  6891.  /* be mailed to the author for consideration for addition to the    */         
  6892.  /* software and incorporation in subsequent releases.               */         
  6893.  /*                                                                  */         
  6894.  /********************************************************************/         
  6895.                                                                                 
  6896. /*=====================================================================         
  6897.  *                                                                              
  6898.  * Command: HELP                                                                
  6899.  *                                                                              
  6900.  * Syntax:  HELP {word}*                                                        
  6901.  *                                                                              
  6902.  * Mode:    any                                                                 
  6903.  *                                                                              
  6904.  * Function: Writes help information to the output file.                        
  6905.  *                                                                              
  6906.  * Note: Words may be specified, but are currently ignored.  All                
  6907.  *       arguments are flushed until a new line or ';' is seen.                 
  6908.  *                                                                              
  6909.  * Examples:  HELP                                                              
  6910.  *            HELP FOR                                                          
  6911.  *            HELP "anything" (at all), it doesn't matter!                      
  6912.  *                                                                              
  6913.  *====================================================================*/        
  6914.                                                                                 
  6915. #pragma  csect(code,  "NN@BPHEL")                                               
  6916. #pragma  csect(static,"NN$BPHEL")                                               
  6917. #include "nn.h"                                                                 
  6918. #include "nnbatch.h"                                                            
  6919.                                                                                 
  6920. /****** Execute batch HELP       command. ****************************/         
  6921.                                                                                 
  6922. static void                                                                     
  6923. NNMbxhel(np,bp,cmdp)                                                            
  6924. Rstruc nncb         *np;                                                        
  6925. Rstruc batch        *bp;                                                        
  6926. Rstruc newscmd      *cmdp;                                                      
  6927. {                                                                               
  6928.  FILE               *helpfp;                                                    
  6929.  char                helpline[257];                                             
  6930.                                                                                 
  6931.  if (!(helpfp = fopen("DD:NNBATHLP","r"))) {                                    
  6932.    perror("ddname NNBATHLP");                                                   
  6933.    fprintf(np->batch_outfile,                                                   
  6934.      "\n\n*** Help not available - cannot open batch help file. ***\n");        
  6935.    return;                                                                      
  6936.  }                                                                              
  6937.  for (;;) {                                                                     
  6938.    fgets(helpline, sizeof(helpline), helpfp);                                   
  6939.    if (feof(helpfp))  break;                                                    
  6940.    if (ferror(helpfp)) {                                                        
  6941.      fprintf(np->batch_outfile,                                                 
  6942.            "\n\n*** Help terminated - error reading help file. ***\n");         
  6943.      break;                                                                     
  6944.    }                                                                            
  6945.    fprintf(np->batch_outfile,"%s",helpline);                                    
  6946.  }                                                                              
  6947.  fprintf(np->batch_outfile,"\n");                                               
  6948.  fclose(helpfp);                                                                
  6949.                                                                                 
  6950.  return;                                                                        
  6951. }                                                                               
  6952.                                                                                 
  6953. /****** Parse batch HELP         command. ****************************/         
  6954.                                                                                 
  6955. struct newscmd *                                                                
  6956. NNMbphel(np,bp)                                                                 
  6957. Rstruc nncb         *np;                                                        
  6958. Rstruc batch        *bp;                                                        
  6959. {                                                                               
  6960.  struct newscmd     *cmdp;                                                      
  6961.                                                                                 
  6962.  bp->stop_at_newline = TRUE;                                                    
  6963.                                                                                 
  6964.  while (NNMbgtok(np,bp,TOKEN_READ)) { /* Get token */                           
  6965.    switch (bp->curtok.type) {                                                   
  6966.      case EOF_TOKEN:                                                            
  6967.      case EOL_TOKEN:                                                            
  6968.      case SEMI_TOKEN: break;                                                    
  6969.      default:         NNMbsynt(np,bp,bp->curtok.string,0,                       
  6970.                                "Extraneous parameter for HELP");                
  6971.                       continue;                                                 
  6972.    }                                                                            
  6973.    break;                                                                       
  6974.  }                                                                              
  6975.                                                                                 
  6976.  if (bp->syntax_error) return NULL;                                             
  6977.                                                                                 
  6978.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for HELP command");                  
  6979.                                                                                 
  6980.  if (cmdp) {                                                                    
  6981.    cmdp->mode = ANY_MODE;                                                       
  6982.    cmdp->proc = NNMbxhel;                                                       
  6983.  }                                                                              
  6984.                                                                                 
  6985.  return cmdp;                                                                   
  6986.                                                                                 
  6987. }                                                                               
  6988.                                                                                 
  6989. ./   ADD NAME=NNMBPIF,SSI=01080016                                              
  6990.                                                                                 
  6991.  /********************************************************************/         
  6992.  /*                                                                  */         
  6993.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  6994.  /*                                                                  */         
  6995.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  6996.  /* including the implied warranties of merchantability and fitness, */         
  6997.  /* are expressly denied.                                            */         
  6998.  /*                                                                  */         
  6999.  /* Provided this copyright notice is included, this software may    */         
  7000.  /* be freely distributed and not offered for sale.                  */         
  7001.  /*                                                                  */         
  7002.  /* Changes or modifications may be made and used only by the maker  */         
  7003.  /* of same, and not further distributed.  Such modifications should */         
  7004.  /* be mailed to the author for consideration for addition to the    */         
  7005.  /* software and incorporation in subsequent releases.               */         
  7006.  /*                                                                  */         
  7007.  /********************************************************************/         
  7008.                                                                                 
  7009. /*=====================================================================         
  7010.  *                                                                              
  7011.  * Command: IF                                                                  
  7012.  *                                                                              
  7013.  * Syntax:  IF condition THEN DO;                                               
  7014.  *          command(s);                                                         
  7015.  *          END;                                                                
  7016.  *          ELSE DO;                                                            
  7017.  *          command(s);                                                         
  7018.  *          END;                                                                
  7019.  *                                                                              
  7020.  *          where                                                               
  7021.  *                                                                              
  7022.  *          condition is any flag expression                                    
  7023.  *                                                                              
  7024.  *          commands are any commands for the appropriate mode                  
  7025.  *                                                                              
  7026.  * Examples:                                                                    
  7027.  *                                                                              
  7028.  *   IF AUTOREGISTER THEN DO ...                                                
  7029.  *   IF SERVER != "" THEN DO ...                                                
  7030.  *   IF (A = 1 | B = 2)  THEN DO ...                                            
  7031.  *                                                                              
  7032.  * Mode:    any (but see note)                                                  
  7033.  *                                                                              
  7034.  * The commands between DO and END, for the THEN and ELSE groups,               
  7035.  * must be in the appropriate mode.                                             
  7036.  *                                                                              
  7037.  * Function: If condition is true, executes commands in the first               
  7038.  *           command group; otherwise executes commands in the second           
  7039.  *           command group.                                                     
  7040.  *                                                                              
  7041.  *====================================================================*/        
  7042.                                                                                 
  7043. #pragma  csect(code,  "NN@BPIF ")                                               
  7044. #pragma  csect(static,"NN$BPIF ")                                               
  7045. #include "nn.h"                                                                 
  7046. #include "nnbatch.h"                                                            
  7047.                                                                                 
  7048. /****** Execute commands. ********************************************/         
  7049.                                                                                 
  7050. static void                                                                     
  7051. execute_commands(np,bp,treep)                                                   
  7052. Rstruc nncb                 *np;                                                
  7053. Rstruc batch                *bp;                                                
  7054. struct cmdtree              *treep;                                             
  7055. {                                                                               
  7056.                                                                                 
  7057.  for (; treep; treep = treep->next) {                                           
  7058.    bp->runtime_error = FALSE;                                                   
  7059.    (treep->cmd->proc) (np,bp,treep->cmd);                                       
  7060.    SETB("ERROR",bp->runtime_error);                                             
  7061.  }                                                                              
  7062.                                                                                 
  7063.  return;                                                                        
  7064. }                                                                               
  7065.                                                                                 
  7066. /****** Execute batch IF command. ************************************/         
  7067.                                                                                 
  7068. static void                                                                     
  7069. NNMbxif(np,bp,cmdp)                                                             
  7070. Rstruc nncb                 *np;                                                
  7071. Rstruc batch                *bp;                                                
  7072. Rstruc newscmd              *cmdp;                                              
  7073. {                                                                               
  7074.  struct ptree               *condition;                                         
  7075.  struct cmdtree             *thencmds;                                          
  7076.  struct cmdtree             *elsecmds;                                          
  7077.  Fool                        condval;                                           
  7078.                                                                                 
  7079.  condition = cmdp->cmd.fcmd.condition;                                          
  7080.  thencmds  = cmdp->cmd.fcmd.thencmds;                                           
  7081.  elsecmds  = cmdp->cmd.fcmd.elsecmds;                                           
  7082.                                                                                 
  7083.  condval = (Fool) NNMbbexp(np,bp,condition,FLAG_SYMTYPE);                       
  7084.  if (bp->runtime_error) return;                                                 
  7085.                                                                                 
  7086.  if (condval) execute_commands(np,bp,thencmds);                                 
  7087.  else         execute_commands(np,bp,elsecmds);                                 
  7088.                                                                                 
  7089.  return;                                                                        
  7090. }                                                                               
  7091.                                                                                 
  7092. /****** Get keyword. *************************************************/         
  7093.                                                                                 
  7094. static Bool                                                                     
  7095. get_keyword(np,bp,key)                                                          
  7096. Rstruc nncb                 *np;                                                
  7097. Rstruc batch                *bp;                                                
  7098. char                        *key;                                               
  7099. {                                                                               
  7100.  struct token               *tp;                                                
  7101.                                                                                 
  7102.  if ((tp = PEEK())                                                              
  7103.   && tp->type == WORD_TOKEN                                                     
  7104.   && EQUAL(tp->string,key)) {                                                   
  7105.    EAT();                                                                       
  7106.    return TRUE;                                                                 
  7107.  }                                                                              
  7108.                                                                                 
  7109.  else return FALSE;                                                             
  7110.                                                                                 
  7111. }                                                                               
  7112.                                                                                 
  7113. /****** Parse batch IF           command. ****************************/         
  7114.                                                                                 
  7115. struct newscmd *                                                                
  7116. NNMbpif(np,bp)                                                                  
  7117. Rstruc nncb         *np;                                                        
  7118. Rstruc batch        *bp;                                                        
  7119. {                                                                               
  7120.  struct newscmd             *cmdp       = NULL;                                 
  7121.  struct ptree               *condition  = NULL;                                 
  7122.  struct cmdtree             *thencmds   = NULL;                                 
  7123.                                                                                 
  7124.  /* Look for condition */                                                       
  7125.                                                                                 
  7126.  condition = NNMbgexp(np,bp,FLAG_SYMTYPE);                                      
  7127.                                                                                 
  7128.  if (condition == NULL) {                                                       
  7129.    NNMbsynt(np,bp,NULL,0,"Missing IF condition");                               
  7130.    return NULL;                                                                 
  7131.  }                                                                              
  7132.                                                                                 
  7133.  /* Look for THEN (required).  */                                               
  7134.                                                                                 
  7135.  if (!(get_keyword(np,bp,"THEN"))) {                                            
  7136.    NNMbsynt(np,bp,NULL,0,"Missing THEN keyword");                               
  7137.    return NULL;                                                                 
  7138.  }                                                                              
  7139.                                                                                 
  7140.  /* Get DO-END command group.                                                   
  7141.   */                                                                            
  7142.                                                                                 
  7143.  thencmds = NNMbgdo(np,bp,bp->mode);                                            
  7144.                                                                                 
  7145.  if (bp->syntax_error) return NULL;                                             
  7146.                                                                                 
  7147.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for IF command");                    
  7148.                                                                                 
  7149.  if (cmdp) {                                                                    
  7150.    cmdp->mode = bp->mode;                                                       
  7151.    cmdp->proc = NNMbxif;                                                        
  7152.    cmdp->cmd.fcmd.condition  = condition;                                       
  7153.    cmdp->cmd.fcmd.thencmds   = thencmds;                                        
  7154.    cmdp->cmd.fcmd.elsecmds   = NULL;                                            
  7155.  }                                                                              
  7156.                                                                                 
  7157.  /* Make sure any following ELSE is properly handled. */                        
  7158.                                                                                 
  7159.  bp->ifcmd = cmdp;                                                              
  7160.                                                                                 
  7161.  return cmdp;                                                                   
  7162.                                                                                 
  7163. }                                                                               
  7164.                                                                                 
  7165. ./   ADD NAME=NNMBPLIS,SSI=01030035                                             
  7166.                                                                                 
  7167.  /********************************************************************/         
  7168.  /*                                                                  */         
  7169.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  7170.  /*                                                                  */         
  7171.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  7172.  /* including the implied warranties of merchantability and fitness, */         
  7173.  /* are expressly denied.                                            */         
  7174.  /*                                                                  */         
  7175.  /* Provided this copyright notice is included, this software may    */         
  7176.  /* be freely distributed and not offered for sale.                  */         
  7177.  /*                                                                  */         
  7178.  /* Changes or modifications may be made and used only by the maker  */         
  7179.  /* of same, and not further distributed.  Such modifications should */         
  7180.  /* be mailed to the author for consideration for addition to the    */         
  7181.  /* software and incorporation in subsequent releases.               */         
  7182.  /*                                                                  */         
  7183.  /********************************************************************/         
  7184.                                                                                 
  7185. /*=====================================================================         
  7186.  *                                                                              
  7187.  * Command: LIST                                                                
  7188.  *                                                                              
  7189.  * Syntax:  LIST                                                                
  7190.  *                                                                              
  7191.  * Mode:    per_article                                                         
  7192.  *                                                                              
  7193.  * Function: Lists the contents of the current news article.                    
  7194.  *                                                                              
  7195.  * Note: Arguments are not permitted.  If they are given, the                   
  7196.  *       function will not be performed.                                        
  7197.  *                                                                              
  7198.  * Examples:  LIST                                                              
  7199.  *                                                                              
  7200.  *====================================================================*/        
  7201.                                                                                 
  7202. #pragma  csect(code,  "NN@BPLIS")                                               
  7203. #pragma  csect(static,"NN$BPLIS")                                               
  7204. #include "nn.h"                                                                 
  7205. #include "nnbatch.h"                                                            
  7206.                                                                                 
  7207. /********** Execute batch LIST command. ******************************/         
  7208.                                                                                 
  7209. static void                                                                     
  7210. NNMbxlis(np,bp,cmdp)                                                            
  7211. Rstruc nncb         *np;                                                        
  7212. Rstruc batch        *bp;                                                        
  7213. Rstruc newscmd      *cmdp;                                                      
  7214. {                                                                               
  7215.  struct newsarticle *ap = bp->ap;                                               
  7216.                                                                                 
  7217.  NNMpick(np,ap);                    /* Pick article */                          
  7218.                                                                                 
  7219.  NNMbtext(np,&ap->thdr,NULL);   /* Print text */                                
  7220.                                                                                 
  7221.  return;                                                                        
  7222.                                                                                 
  7223. }                                                                               
  7224.                                                                                 
  7225. /****** Parse batch LIST command. ************************************/         
  7226.                                                                                 
  7227. struct newscmd *                                                                
  7228. NNMbplis(np,bp)                                                                 
  7229. Rstruc nncb         *np;                                                        
  7230. Rstruc batch        *bp;                                                        
  7231. {                                                                               
  7232.  struct newscmd     *cmdp;                                                      
  7233.                                                                                 
  7234.  bp->stop_at_newline = TRUE;                                                    
  7235.                                                                                 
  7236.  NNMbtras(np,bp,"LIST");   /* Trash extraneous parameters */                    
  7237.                                                                                 
  7238.  if (bp->syntax_error) return NULL;                                             
  7239.                                                                                 
  7240.  if (bp->mode != PER_ARTICLE_MODE) {                                            
  7241.    NNMbsynt(np,bp,NULL,0,                                                       
  7242.             "LIST is invalid outside of per-article mode");                     
  7243.    return NULL;                                                                 
  7244.  }                                                                              
  7245.                                                                                 
  7246.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for LIST command");                  
  7247.                                                                                 
  7248.  if (cmdp) {                                                                    
  7249.    cmdp->mode = PER_ARTICLE_MODE;                                               
  7250.    cmdp->proc = NNMbxlis;                                                       
  7251.  }                                                                              
  7252.                                                                                 
  7253.  return cmdp;                                                                   
  7254.                                                                                 
  7255. }                                                                               
  7256.                                                                                 
  7257. ./   ADD NAME=NNMBPMAR,SSI=01050054                                             
  7258.                                                                                 
  7259.  /********************************************************************/         
  7260.  /*                                                                  */         
  7261.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  7262.  /*                                                                  */         
  7263.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  7264.  /* including the implied warranties of merchantability and fitness, */         
  7265.  /* are expressly denied.                                            */         
  7266.  /*                                                                  */         
  7267.  /* Provided this copyright notice is included, this software may    */         
  7268.  /* be freely distributed and not offered for sale.                  */         
  7269.  /*                                                                  */         
  7270.  /* Changes or modifications may be made and used only by the maker  */         
  7271.  /* of same, and not further distributed.  Such modifications should */         
  7272.  /* be mailed to the author for consideration for addition to the    */         
  7273.  /* software and incorporation in subsequent releases.               */         
  7274.  /*                                                                  */         
  7275.  /********************************************************************/         
  7276.                                                                                 
  7277. /*=====================================================================         
  7278.  *                                                                              
  7279.  * Command: MARK                                                                
  7280.  *                                                                              
  7281.  * Syntax:  MARK { READ / UNREAD }                                              
  7282.  *                                                                              
  7283.  * Default: MARK READ                                                           
  7284.  *                                                                              
  7285.  * Mode:    per-article                                                         
  7286.  *                                                                              
  7287.  * Function: Marks the article read or unread.                                  
  7288.  *                                                                              
  7289.  * Examples:  MARK                                                              
  7290.  *            MARK READ                                                         
  7291.  *            MARK UNREAD                                                       
  7292.  *                                                                              
  7293.  *====================================================================*/        
  7294.                                                                                 
  7295. #pragma  csect(code,  "NN@BPMAR")                                               
  7296. #pragma  csect(static,"NN$BPMAR")                                               
  7297. #include "nn.h"                                                                 
  7298. #include "nnbatch.h"                                                            
  7299.                                                                                 
  7300. /********** Execute batch MARK command. ******************************/         
  7301.                                                                                 
  7302. static void                                                                     
  7303. NNMbxmar(np,bp,cmdp)                                                            
  7304. Rstruc nncb         *np;                                                        
  7305. Rstruc batch        *bp;                                                        
  7306. Rstruc newscmd      *cmdp;                                                      
  7307. {                                                                               
  7308.  struct newsgroup   *gp = bp->gp;                                               
  7309.  struct newsarticle *ap = bp->ap;                                               
  7310.  char               *what = "not";                                              
  7311.                                                                                 
  7312.  switch (cmdp->cmd.rcmd.marking) {                                              
  7313.    case MARKING_READ:                                                           
  7314.                         NNMmarr(np,gp,ap);                                      
  7315.                         what = "read";                                          
  7316.                         break;                                                  
  7317.    case MARKING_UNREAD:                                                         
  7318.                         NNMmaru(np,gp,ap);                                      
  7319.                         what = "unread";                                        
  7320.                         break;                                                  
  7321.  }                                                                              
  7322.                                                                                 
  7323.  fprintf(np->batch_outfile,                                                     
  7324.          "Article %d of %s marked %s.\n",                                       
  7325.          ap->number,                                                            
  7326.          gp->name,                                                              
  7327.          what);                                                                 
  7328.                                                                                 
  7329.  NNMsave(np,NULL);   /* Checkpoint NEWSRC file */                               
  7330.                                                                                 
  7331.  return;                                                                        
  7332.                                                                                 
  7333. }                                                                               
  7334.                                                                                 
  7335. /****** Parse batch MARK         command. ****************************/         
  7336.                                                                                 
  7337. struct newscmd *                                                                
  7338. NNMbpmar(np,bp)                                                                 
  7339. Rstruc nncb         *np;                                                        
  7340. Rstruc batch        *bp;                                                        
  7341. {                                                                               
  7342.  struct newscmd     *cmdp       = NULL;                                         
  7343.  enum marking_mode   marking    = MARKING_READ;                                 
  7344.                                                                                 
  7345.  /*                                                                             
  7346.   * Next token, if present, must be READ or UNREAD.                             
  7347.   */                                                                            
  7348.                                                                                 
  7349.  if (NNMbgtok(np,bp,TOKEN_READ)) {  /* get token */                             
  7350.    switch (bp->curtok.type) {                                                   
  7351.      case EOL_TOKEN:                                                            
  7352.      case EOF_TOKEN:                                                            
  7353.      case SEMI_TOKEN: marking = MARKING_READ;                                   
  7354.                       break;                                                    
  7355.      case WORD_TOKEN:                                                           
  7356.                       if (EQUAL(bp->curtok.string,"READ")) {                    
  7357.                         marking = MARKING_READ;                                 
  7358.                       }                                                         
  7359.                       else if (EQUAL(bp->curtok.string,"UNREAD")) {             
  7360.                         marking = MARKING_UNREAD;                               
  7361.                       }                                                         
  7362.                       else {                                                    
  7363.                         NNMbsynt(np,bp,bp->curtok.string,0,                     
  7364.                                  "MARK operand must be READ or UNREAD");        
  7365.                       }                                                         
  7366.                       break;                                                    
  7367.      default:                                                                   
  7368.                       NNMbsynt(np,bp,bp->curtok.string,0,                       
  7369.                                "MARK operand must be READ or UNREAD");          
  7370.                       break;                                                    
  7371.    }                                                                            
  7372.  }                                                                              
  7373.                                                                                 
  7374.  bp->stop_at_newline = TRUE;                                                    
  7375.                                                                                 
  7376.  NNMbtras(np,bp,"MARK");   /* Trash extraneous parameters */                    
  7377.                                                                                 
  7378.  if (bp->syntax_error) return NULL;                                             
  7379.                                                                                 
  7380.  if (bp->mode != PER_ARTICLE_MODE) {                                            
  7381.    NNMbsynt(np,bp,NULL,0,                                                       
  7382.             "MARK is invalid outside of per-article mode");                     
  7383.    return NULL;                                                                 
  7384.  }                                                                              
  7385.                                                                                 
  7386.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for MARK command");                  
  7387.                                                                                 
  7388.  if (cmdp) {                                                                    
  7389.    cmdp->mode = PER_ARTICLE_MODE;                                               
  7390.    cmdp->proc = NNMbxmar;                                                       
  7391.    cmdp->cmd.rcmd.marking = marking;                                            
  7392.  }                                                                              
  7393.                                                                                 
  7394.  return cmdp;                                                                   
  7395. }                                                                               
  7396.                                                                                 
  7397. ./   ADD NAME=NNMBPNNT,SSI=010D0056                                             
  7398.                                                                                 
  7399.  /********************************************************************/         
  7400.  /*                                                                  */         
  7401.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  7402.  /*                                                                  */         
  7403.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  7404.  /* including the implied warranties of merchantability and fitness, */         
  7405.  /* are expressly denied.                                            */         
  7406.  /*                                                                  */         
  7407.  /* Provided this copyright notice is included, this software may    */         
  7408.  /* be freely distributed and not offered for sale.                  */         
  7409.  /*                                                                  */         
  7410.  /* Changes or modifications may be made and used only by the maker  */         
  7411.  /* of same, and not further distributed.  Such modifications should */         
  7412.  /* be mailed to the author for consideration for addition to the    */         
  7413.  /* software and incorporation in subsequent releases.               */         
  7414.  /*                                                                  */         
  7415.  /********************************************************************/         
  7416.                                                                                 
  7417. /*=====================================================================         
  7418.  *                                                                              
  7419.  * Command: NNTP                                                                
  7420.  *                                                                              
  7421.  * Syntax:  NNTP {datum}* ;                                                     
  7422.  *                                                                              
  7423.  * Mode:    any (but see notes)                                                 
  7424.  *                                                                              
  7425.  * Function: Sends an NNTP protocol command to the server as built              
  7426.  *           from the specified data items.  Items can be:                      
  7427.  *                                                                              
  7428.  *           * text strings                                                     
  7429.  *           * integers                                                         
  7430.  *           * words representing variables that have values                    
  7431.  *                                                                              
  7432.  * Note: When words are used, the values they represent must be                 
  7433.  *       valid for the mode in which the EXEC is executed.                      
  7434.  *                                                                              
  7435.  * Note: The NNTP request must be appropriate for the mode active               
  7436.  *       at the time the request is executed.                                   
  7437.  *                                                                              
  7438.  * Note: Since the command can span input lines and the number of               
  7439.  *       arguments is variable, the arguments MUST be terminated                
  7440.  *       by a semicolon or end of file.                                         
  7441.  *                                                                              
  7442.  * Examples:  NNTP "HELP";                                                      
  7443.  *            NNTP "ARTICLE " NUMBER;                                           
  7444.  *                                                                              
  7445.  *====================================================================*/        
  7446.                                                                                 
  7447. #pragma  csect(code,  "NN@BPNNT")                                               
  7448. #pragma  csect(static,"NN$BPNNT")                                               
  7449. #include "nn.h"                                                                 
  7450. #include "nnbatch.h"                                                            
  7451.                                                                                 
  7452. /****** Execute batch NNTP       command. ****************************/         
  7453.                                                                                 
  7454. static void                                                                     
  7455. NNMbxnnt(np,bp,cmdp)                                                            
  7456. Rstruc nncb         *np;                                                        
  7457. Rstruc batch        *bp;                                                        
  7458. Rstruc newscmd      *cmdp;                                                      
  7459. {                                                                               
  7460.  char               *string;                                                    
  7461.                                                                                 
  7462.  string = NNMbbexp(np,bp,cmdp->cmd.mcmd.ptreep,STRING_SYMTYPE);                 
  7463.  if (bp->runtime_error) {                                                       
  7464.    fprintf(np->batch_outfile,                                                   
  7465.            "NNTP command not sent due to errors building argument\n");          
  7466.    return;                                                                      
  7467.  }                                                                              
  7468.                                                                                 
  7469.  if (!NNMbconn(np,bp)) {  /* Insure server name and connect to server */        
  7470.    fprintf(np->batch_outfile,"NNTP command not executed:\n%s\n\n",              
  7471.                              string);                                           
  7472.    return;                                                                      
  7473.  }                                                                              
  7474.                                                                                 
  7475.  fprintf(np->batch_outfile, "NNTP command:\n%s\n\n", string);                   
  7476.                                                                                 
  7477.  if (*string || np->receiving_text) {                                           
  7478.    if (strlen(string) > CLIENT_BUF_MSGSIZE) {                                   
  7479.      ERR1(                                                                      
  7480.    "Requested NNTP command is longer than NNMVS is prepared to handle."         
  7481.          );                                                                     
  7482.    }                                                                            
  7483.    else {                                                                       
  7484.      strcpy(np->nntp_command,string);                                           
  7485.      NNMnntp(np);                       /* execute NNTP commands */             
  7486.    }                                                                            
  7487.  }                                                                              
  7488.                                                                                 
  7489.  return;                                                                        
  7490.                                                                                 
  7491. }                                                                               
  7492.                                                                                 
  7493. /****** Parse batch NNTP         command. ****************************/         
  7494.                                                                                 
  7495. struct newscmd *                                                                
  7496. NNMbpnnt(np,bp)                                                                 
  7497. Rstruc nncb         *np;                                                        
  7498. Rstruc batch        *bp;                                                        
  7499. {                                                                               
  7500.  struct newscmd     *cmdp       = NULL;                                         
  7501.  struct ptree       *treep      = NULL;                                         
  7502.                                                                                 
  7503.  treep = NNMbgexp(np,bp,STRING_SYMTYPE); /* Get data string struct */           
  7504.                                                                                 
  7505.  if (treep == NULL) {                                                           
  7506.    NNMbsynt(np,bp,NULL,0,"Error in arguments to NNTP");                         
  7507.    return NULL;                                                                 
  7508.  }                                                                              
  7509.                                                                                 
  7510.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for NNTP command");                  
  7511.                                                                                 
  7512.  if (cmdp) {                                                                    
  7513.    cmdp->mode = ANY_MODE;                                                       
  7514.    cmdp->proc = NNMbxnnt;                                                       
  7515.    cmdp->cmd.mcmd.ptreep = treep;                                               
  7516.  }                                                                              
  7517.                                                                                 
  7518.  return cmdp;                                                                   
  7519. }                                                                               
  7520.                                                                                 
  7521. ./   ADD NAME=NNMBPPUT,SSI=01150038                                             
  7522.                                                                                 
  7523.  /********************************************************************/         
  7524.  /*                                                                  */         
  7525.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  7526.  /*                                                                  */         
  7527.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  7528.  /* including the implied warranties of merchantability and fitness, */         
  7529.  /* are expressly denied.                                            */         
  7530.  /*                                                                  */         
  7531.  /* Provided this copyright notice is included, this software may    */         
  7532.  /* be freely distributed and not offered for sale.                  */         
  7533.  /*                                                                  */         
  7534.  /* Changes or modifications may be made and used only by the maker  */         
  7535.  /* of same, and not further distributed.  Such modifications should */         
  7536.  /* be mailed to the author for consideration for addition to the    */         
  7537.  /* software and incorporation in subsequent releases.               */         
  7538.  /*                                                                  */         
  7539.  /********************************************************************/         
  7540.                                                                                 
  7541. /*=====================================================================         
  7542.  *                                                                              
  7543.  * Command: PUT                                                                 
  7544.  *                                                                              
  7545.  * Syntax:  PUT {datum}* ;                                                      
  7546.  *                                                                              
  7547.  * Mode:    any (but see note)                                                  
  7548.  *                                                                              
  7549.  * Function: Writes zero or more items of data to the output file,              
  7550.  *           followed by a newline.  Items can be:                              
  7551.  *                                                                              
  7552.  *           * text strings                                                     
  7553.  *           * integers                                                         
  7554.  *           * words representing variables that have values                    
  7555.  *                                                                              
  7556.  * Note: When words are used, the values they represent must be                 
  7557.  *       valid for the mode in which the PUT is executed.                       
  7558.  *                                                                              
  7559.  * Note: Since the command can span input lines and the number of               
  7560.  *       arguments is variable, the arguments MUST be terminated                
  7561.  *       by a semicolon or end of file.                                         
  7562.  *                                                                              
  7563.  * Examples:  PUT;                                                              
  7564.  *            PUT "Hello, world";                                               
  7565.  *            PUT 666 " is the number of the Beast.";                           
  7566.  *            PUT "I have " UNREAD " new items from server " server ".";        
  7567.  *                                                                              
  7568.  *====================================================================*/        
  7569.                                                                                 
  7570. #pragma  csect(code,  "NN@BPPUT")                                               
  7571. #pragma  csect(static,"NN$BPPUT")                                               
  7572. #include "nn.h"                                                                 
  7573. #include "nnbatch.h"                                                            
  7574.                                                                                 
  7575. /****** Print text line. *********************************************/         
  7576.                                                                                 
  7577. static Bool                                                                     
  7578. print_text_line(fp,string)                                                      
  7579. FILE           *fp;                                                             
  7580. char           *string;                                                         
  7581. {                                                                               
  7582.  char          *cp;                                                             
  7583.  int            l;                                                              
  7584.                                                                                 
  7585.  for (cp = string, l = strlen(string); l > 0; cp += 251, l -= 251) {            
  7586.   fwrite(cp,(l>251 ? 251 : l),1,fp);                                            
  7587.   if (ferror(fp))            return FALSE;                                      
  7588.   if (fputc('\n',fp) == EOF) return FALSE;                                      
  7589.  }                                                                              
  7590.                                                                                 
  7591.  return TRUE;                                                                   
  7592. }                                                                               
  7593.                                                                                 
  7594. /****** Execute batch PUT        command. ****************************/         
  7595.                                                                                 
  7596. static void                                                                     
  7597. NNMbxput(np,bp,cmdp)                                                            
  7598. Rstruc nncb         *np;                                                        
  7599. Rstruc batch        *bp;                                                        
  7600. Rstruc newscmd      *cmdp;                                                      
  7601. {                                                                               
  7602.  struct ptree       *treep;                                                     
  7603.  char               *string;                                                    
  7604.  FILE               *fp;                                                        
  7605.  Bool                print_error;                                               
  7606.                                                                                 
  7607.  treep = cmdp->cmd.mcmd.ptreep;                                                 
  7608.                                                                                 
  7609.  print_error = FALSE;                                                           
  7610.                                                                                 
  7611.  if (treep == NULL) {                                                           
  7612.    fp = NNMbsout(np,bp);  /* Set output file */                                 
  7613.    fprintf(fp,"\n");                                                            
  7614.    if (ferror(fp)) print_error = TRUE;                                          
  7615.  }                                                                              
  7616.  else {                                                                         
  7617.    string = NNMbbexp(np,bp,treep,STRING_SYMTYPE);                               
  7618.    if (bp->runtime_error) {                                                     
  7619.      fprintf(np->batch_outfile,                                                 
  7620.              "\n<<Put failed, error building argument>>\n");                    
  7621.    }                                                                            
  7622.    else {                                                                       
  7623.      fp = NNMbsout(np,bp);  /* Set output file */                               
  7624.      if (!print_text_line(fp,string)) print_error = TRUE;                       
  7625.    }                                                                            
  7626.  }                                                                              
  7627.                                                                                 
  7628.  if (print_error) {                                                             
  7629.    fprintf(stderr,"Error writing to outfile\n");                                
  7630.    bp->runtime_error = TRUE;                                                    
  7631.  }                                                                              
  7632.                                                                                 
  7633.  return;                                                                        
  7634.                                                                                 
  7635. }                                                                               
  7636.                                                                                 
  7637. /****** Parse batch PUT          command. ****************************/         
  7638.                                                                                 
  7639. struct newscmd *                                                                
  7640. NNMbpput(np,bp)                                                                 
  7641. Rstruc nncb         *np;                                                        
  7642. Rstruc batch        *bp;                                                        
  7643. {                                                                               
  7644.  struct newscmd     *cmdp       = NULL;                                         
  7645.  struct ptree       *treep      = NULL;                                         
  7646.                                                                                 
  7647.  /*                                                                             
  7648.   * Special case for PUT without arguments                                      
  7649.   *                                                                             
  7650.   */                                                                            
  7651.                                                                                 
  7652.  if (NNMbgtok(np,bp,TOKEN_PEEK)) {  /* Peek next token */                       
  7653.    switch (bp->nextok.type) {                                                   
  7654.      case EOF_TOKEN:                                                            
  7655.      case EOL_TOKEN:                                                            
  7656.      case SEMI_TOKEN:  treep = NULL;                                            
  7657.                        break;                                                   
  7658.      default:                                                                   
  7659.                        treep = NNMbgexp(np,bp,STRING_SYMTYPE);                  
  7660.                        if (treep == NULL) {                                     
  7661.                          NNMbsynt(np,bp,NULL,0,                                 
  7662.                                   "Error in arguments to PUT");                 
  7663.                          return NULL;                                           
  7664.                        }                                                        
  7665.                        break;                                                   
  7666.    }                                                                            
  7667.  }                                                                              
  7668.                                                                                 
  7669.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for PUT command");                   
  7670.                                                                                 
  7671.  if (cmdp) {                                                                    
  7672.    cmdp->mode = ANY_MODE;                                                       
  7673.    cmdp->proc = NNMbxput;                                                       
  7674.    cmdp->cmd.mcmd.ptreep = treep;                                               
  7675.  }                                                                              
  7676.                                                                                 
  7677.  return cmdp;                                                                   
  7678. }                                                                               
  7679.                                                                                 
  7680. ./   ADD NAME=NNMBPQUE,SSI=01070004                                             
  7681.                                                                                 
  7682.  /********************************************************************/         
  7683.  /*                                                                  */         
  7684.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  7685.  /*                                                                  */         
  7686.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  7687.  /* including the implied warranties of merchantability and fitness, */         
  7688.  /* are expressly denied.                                            */         
  7689.  /*                                                                  */         
  7690.  /* Provided this copyright notice is included, this software may    */         
  7691.  /* be freely distributed and not offered for sale.                  */         
  7692.  /*                                                                  */         
  7693.  /* Changes or modifications may be made and used only by the maker  */         
  7694.  /* of same, and not further distributed.  Such modifications should */         
  7695.  /* be mailed to the author for consideration for addition to the    */         
  7696.  /* software and incorporation in subsequent releases.               */         
  7697.  /*                                                                  */         
  7698.  /********************************************************************/         
  7699.                                                                                 
  7700. /*=====================================================================         
  7701.  *                                                                              
  7702.  * Command: QUERY                                                               
  7703.  *                                                                              
  7704.  * Syntax:  QUERY                                                               
  7705.  *                                                                              
  7706.  * Mode:    per_newsgroup or per_article                                        
  7707.  *                                                                              
  7708.  * Function: Dumps the status of the current newsgroup or article.              
  7709.  *                                                                              
  7710.  * Examples:  QUERY                                                             
  7711.  *                                                                              
  7712.  *====================================================================*/        
  7713.                                                                                 
  7714. #pragma  csect(code,  "NN@BPQUE")                                               
  7715. #pragma  csect(static,"NN$BPQUE")                                               
  7716. #include "nn.h"                                                                 
  7717. #include "nnbatch.h"                                                            
  7718.                                                                                 
  7719. /****** Execute batch QUERY      command. ****************************/         
  7720.                                                                                 
  7721. static void                                                                     
  7722. NNMbxque(np,bp,cmdp)                                                            
  7723. Rstruc nncb         *np;                                                        
  7724. Rstruc batch        *bp;                                                        
  7725. Rstruc newscmd      *cmdp;                                                      
  7726. {                                                                               
  7727.                                                                                 
  7728.  switch (cmdp->mode) {                                                          
  7729.    case PER_NEWSGROUP_MODE:  NNMqng (np,bp->gp);                                
  7730.                              break;                                             
  7731.    case PER_ARTICLE_MODE:    NNMqar (np,bp->ap);                                
  7732.                              break;                                             
  7733.    default: return;                                                             
  7734.  }                                                                              
  7735.                                                                                 
  7736.  return;                                                                        
  7737.                                                                                 
  7738. }                                                                               
  7739.                                                                                 
  7740. /****** Parse batch QUERY        command. ****************************/         
  7741.                                                                                 
  7742. struct newscmd *                                                                
  7743. NNMbpque(np,bp)                                                                 
  7744. Rstruc nncb         *np;                                                        
  7745. Rstruc batch        *bp;                                                        
  7746. {                                                                               
  7747.  struct newscmd     *cmdp;                                                      
  7748.                                                                                 
  7749.  bp->stop_at_newline = TRUE;                                                    
  7750.                                                                                 
  7751.  NNMbtras(np,bp,"QUERY");        /* Trash extraneous parameters */              
  7752.                                                                                 
  7753.  if (bp->syntax_error) return NULL;                                             
  7754.                                                                                 
  7755.  switch (bp->mode) {                                                            
  7756.    case PER_NEWSGROUP_MODE:                                                     
  7757.    case PER_ARTICLE_MODE:                                                       
  7758.         break;                                                                  
  7759.    default:                                                                     
  7760.         NNMbsynt(np,bp,NULL,0,                                                  
  7761.             "QUERY is valid only in per-newsgroup or per-article mode");        
  7762.    return NULL;                                                                 
  7763.  }                                                                              
  7764.                                                                                 
  7765.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for QUERY command");                 
  7766.                                                                                 
  7767.  if (cmdp) {                                                                    
  7768.    cmdp->mode = bp->mode;                                                       
  7769.    cmdp->proc = NNMbxque;                                                       
  7770.  }                                                                              
  7771.                                                                                 
  7772.  return cmdp;                                                                   
  7773.                                                                                 
  7774. }                                                                               
  7775.                                                                                 
  7776. ./   ADD NAME=NNMBPQUI,SSI=010B0031                                             
  7777.                                                                                 
  7778.  /********************************************************************/         
  7779.  /*                                                                  */         
  7780.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  7781.  /*                                                                  */         
  7782.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  7783.  /* including the implied warranties of merchantability and fitness, */         
  7784.  /* are expressly denied.                                            */         
  7785.  /*                                                                  */         
  7786.  /* Provided this copyright notice is included, this software may    */         
  7787.  /* be freely distributed and not offered for sale.                  */         
  7788.  /*                                                                  */         
  7789.  /* Changes or modifications may be made and used only by the maker  */         
  7790.  /* of same, and not further distributed.  Such modifications should */         
  7791.  /* be mailed to the author for consideration for addition to the    */         
  7792.  /* software and incorporation in subsequent releases.               */         
  7793.  /*                                                                  */         
  7794.  /********************************************************************/         
  7795.                                                                                 
  7796. /*=====================================================================         
  7797.  *                                                                              
  7798.  * Command: QUIT                                                                
  7799.  *                                                                              
  7800.  * Syntax:  QUIT                                                                
  7801.  *                                                                              
  7802.  * Mode:    any                                                                 
  7803.  *                                                                              
  7804.  * Function: Terminates processing when it is seen.                             
  7805.  *                                                                              
  7806.  * Note: Arguments are not permitted.  If they are given, the QUIT              
  7807.  *       function will not be performed.                                        
  7808.  *                                                                              
  7809.  * Examples:  QUIT                                                              
  7810.  *                                                                              
  7811.  *====================================================================*/        
  7812.                                                                                 
  7813. #pragma  csect(code,  "NN@BPQUI")                                               
  7814. #pragma  csect(static,"NN$BPQUI")                                               
  7815. #include "nn.h"                                                                 
  7816. #include "nnbatch.h"                                                            
  7817.                                                                                 
  7818. /****** Execute batch QUIT       command. ****************************/         
  7819.                                                                                 
  7820. static void                                                                     
  7821. NNMbxqui(np,bp,cmdp)                                                            
  7822. Rstruc nncb         *np;                                                        
  7823. Rstruc batch        *bp;                                                        
  7824. Rstruc newscmd      *cmdp;                                                      
  7825. {                                                                               
  7826.                                                                                 
  7827.  bp->quit = TRUE;                                                               
  7828.                                                                                 
  7829.  fprintf(np->batch_outfile,"\nQUIT signalled.  Processing ended.\n");           
  7830.                                                                                 
  7831.  return;                                                                        
  7832.                                                                                 
  7833. }                                                                               
  7834.                                                                                 
  7835. /****** Parse batch QUIT         command. ****************************/         
  7836.                                                                                 
  7837. struct newscmd *                                                                
  7838. NNMbpqui(np,bp)                                                                 
  7839. Rstruc nncb         *np;                                                        
  7840. Rstruc batch        *bp;                                                        
  7841. {                                                                               
  7842.  struct newscmd     *cmdp;                                                      
  7843.                                                                                 
  7844.  bp->stop_at_newline = TRUE;                                                    
  7845.                                                                                 
  7846.  NNMbtras(np,bp,"QUIT");   /* Trash extraneous parameters */                    
  7847.                                                                                 
  7848.  if (bp->syntax_error) return NULL;                                             
  7849.                                                                                 
  7850.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for QUIT command");                  
  7851.                                                                                 
  7852.  if (cmdp) {                                                                    
  7853.    cmdp->mode = ANY_MODE;                                                       
  7854.    cmdp->proc = NNMbxqui;                                                       
  7855.  }                                                                              
  7856.                                                                                 
  7857.  return cmdp;                                                                   
  7858.                                                                                 
  7859. }                                                                               
  7860.                                                                                 
  7861. ./   ADD NAME=NNMBPREG,SSI=010A0050                                             
  7862.                                                                                 
  7863.  /********************************************************************/         
  7864.  /*                                                                  */         
  7865.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  7866.  /*                                                                  */         
  7867.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  7868.  /* including the implied warranties of merchantability and fitness, */         
  7869.  /* are expressly denied.                                            */         
  7870.  /*                                                                  */         
  7871.  /* Provided this copyright notice is included, this software may    */         
  7872.  /* be freely distributed and not offered for sale.                  */         
  7873.  /*                                                                  */         
  7874.  /* Changes or modifications may be made and used only by the maker  */         
  7875.  /* of same, and not further distributed.  Such modifications should */         
  7876.  /* be mailed to the author for consideration for addition to the    */         
  7877.  /* software and incorporation in subsequent releases.               */         
  7878.  /*                                                                  */         
  7879.  /********************************************************************/         
  7880.                                                                                 
  7881. /*=====================================================================         
  7882.  *                                                                              
  7883.  * Command: REGISTER                                                            
  7884.  *                                                                              
  7885.  * Syntax:  REGISTER                                                            
  7886.  *                                                                              
  7887.  * Mode:    per_newsgroup                                                       
  7888.  *                                                                              
  7889.  * Function: Registers the current newsgroup.                                   
  7890.  *                                                                              
  7891.  * Note: Arguments are not permitted.  If they are given, the                   
  7892.  *       function will not be performed.                                        
  7893.  *                                                                              
  7894.  * Examples:  REGISTER                                                          
  7895.  *                                                                              
  7896.  *====================================================================*/        
  7897.                                                                                 
  7898. #pragma  csect(code,  "NN@BPREG")                                               
  7899. #pragma  csect(static,"NN$BPREG")                                               
  7900. #include "nn.h"                                                                 
  7901. #include "nnbatch.h"                                                            
  7902.                                                                                 
  7903. /****** Execute batch REGISTER command. ******************************/         
  7904.                                                                                 
  7905. static void                                                                     
  7906. NNMbxreg(np,bp,cmdp)                                                            
  7907. Rstruc nncb         *np;                                                        
  7908. Rstruc batch        *bp;                                                        
  7909. Rstruc newscmd      *cmdp;                                                      
  7910. {                                                                               
  7911.  Rstruc newsgroup   *gp = bp->gp;                                               
  7912.                                                                                 
  7913.  gp->registered = 1;                                                            
  7914.                                                                                 
  7915.  fprintf(np->batch_outfile,"Newsgroup %s registered.\n",gp->name);              
  7916.                                                                                 
  7917.  NNMsave(np,NULL);   /* Checkpoint NEWSRC file */                               
  7918.                                                                                 
  7919.  return;                                                                        
  7920.                                                                                 
  7921. }                                                                               
  7922.                                                                                 
  7923. /****** Parse batch REGISTER command. ********************************/         
  7924.                                                                                 
  7925. struct newscmd *                                                                
  7926. NNMbpreg(np,bp)                                                                 
  7927. Rstruc nncb         *np;                                                        
  7928. Rstruc batch        *bp;                                                        
  7929. {                                                                               
  7930.  struct newscmd     *cmdp;                                                      
  7931.                                                                                 
  7932.  bp->stop_at_newline = TRUE;                                                    
  7933.                                                                                 
  7934.  NNMbtras(np,bp,"REGISTER");   /* Trash extraneous parameters */                
  7935.                                                                                 
  7936.  if (bp->syntax_error) return NULL;                                             
  7937.                                                                                 
  7938.  if (bp->mode != PER_NEWSGROUP_MODE) {                                          
  7939.    NNMbsynt(np,bp,NULL,0,                                                       
  7940.             "REGISTER is invalid outside of per-newsgroup mode");               
  7941.    return NULL;                                                                 
  7942.  }                                                                              
  7943.                                                                                 
  7944.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for REGISTER command");              
  7945.                                                                                 
  7946.  if (cmdp) {                                                                    
  7947.    cmdp->mode = PER_NEWSGROUP_MODE;                                             
  7948.    cmdp->proc = NNMbxreg;                                                       
  7949.  }                                                                              
  7950.                                                                                 
  7951.  return cmdp;                                                                   
  7952.                                                                                 
  7953. }                                                                               
  7954.                                                                                 
  7955. ./   ADD NAME=NNMBPSET,SSI=01160009                                             
  7956.                                                                                 
  7957.  /********************************************************************/         
  7958.  /*                                                                  */         
  7959.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  7960.  /*                                                                  */         
  7961.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  7962.  /* including the implied warranties of merchantability and fitness, */         
  7963.  /* are expressly denied.                                            */         
  7964.  /*                                                                  */         
  7965.  /* Provided this copyright notice is included, this software may    */         
  7966.  /* be freely distributed and not offered for sale.                  */         
  7967.  /*                                                                  */         
  7968.  /* Changes or modifications may be made and used only by the maker  */         
  7969.  /* of same, and not further distributed.  Such modifications should */         
  7970.  /* be mailed to the author for consideration for addition to the    */         
  7971.  /* software and incorporation in subsequent releases.               */         
  7972.  /*                                                                  */         
  7973.  /********************************************************************/         
  7974.                                                                                 
  7975. /*=====================================================================         
  7976.  *                                                                              
  7977.  * Command: SET                                                                 
  7978.  *                                                                              
  7979.  * Syntax:  SET variablename {=} {value-datum}*                                 
  7980.  *                                                                              
  7981.  * Mode:    any (but see note)                                                  
  7982.  *                                                                              
  7983.  * Function: Assigns a value to the specified variablename so                   
  7984.  *           that it can be referenced in later PUT statements or               
  7985.  *           condition queries.  Value can be made up of:                       
  7986.  *                                                                              
  7987.  *           * text strings                                                     
  7988.  *           * integers                                                         
  7989.  *           * words representing other variables that have values              
  7990.  *                                                                              
  7991.  * Note: When words are used, the values they represent must be                 
  7992.  *       valid for the mode in which the SET is executed.                       
  7993.  *                                                                              
  7994.  * Note: Since the command can span input lines and the number of               
  7995.  *       arguments is variable, the arguments MUST be terminated                
  7996.  *       by a semicolon or end of file.                                         
  7997.  *                                                                              
  7998.  * Note: The type of the value is determined by the declared type               
  7999.  *       of the variable being set.                                             
  8000.  *                                                                              
  8001.  * Examples:  SET SERVER "foo.news.com"                                         
  8002.  *            SET COUNT = 1                                                     
  8003.  *            SET MESSAGE = "There are " UNREAD "new items."                    
  8004.  *                                                                              
  8005.  *====================================================================*/        
  8006.                                                                                 
  8007. #pragma  csect(code,  "NN@BPSET")                                               
  8008. #pragma  csect(static,"NN$BPSET")                                               
  8009. #include "nn.h"                                                                 
  8010. #include "nnbatch.h"                                                            
  8011.                                                                                 
  8012. /****** Execute batch SET        command. ****************************/         
  8013.                                                                                 
  8014. static void                                                                     
  8015. NNMbxset(np,bp,cmdp)                                                            
  8016. Rstruc nncb         *np;                                                        
  8017. Rstruc batch        *bp;                                                        
  8018. Rstruc newscmd      *cmdp;                                                      
  8019. {                                                                               
  8020.  char               *string;                                                    
  8021.  int                 number;                                                    
  8022.  Fool                flag;                                                      
  8023.  char               *var;                                                       
  8024.                                                                                 
  8025.  var = cmdp->cmd.scmd.set_symbol;                                               
  8026.                                                                                 
  8027.  switch (cmdp->cmd.scmd.set_type) {                                             
  8028.    case STRING_SYMTYPE:                                                         
  8029.         string = (char *)                                                       
  8030.                  NNMbbexp(np,bp,cmdp->cmd.scmd.ptreep,STRING_SYMTYPE);          
  8031.         if (!bp->runtime_error) {                                               
  8032.           SETC(var,string);                                                     
  8033.         }                                                                       
  8034.         break;                                                                  
  8035.    case NUMBER_SYMTYPE:                                                         
  8036.         number = (int)                                                          
  8037.                  NNMbbexp(np,bp,cmdp->cmd.scmd.ptreep,NUMBER_SYMTYPE);          
  8038.         if (!bp->runtime_error) {                                               
  8039.           SETA(var,number);                                                     
  8040.         }                                                                       
  8041.         break;                                                                  
  8042.    case FLAG_SYMTYPE:                                                           
  8043.         flag   = (Fool)                                                         
  8044.                  NNMbbexp(np,bp,cmdp->cmd.scmd.ptreep,FLAG_SYMTYPE);            
  8045.         if (!bp->runtime_error) {                                               
  8046.           SETB(var,flag);                                                       
  8047.         }                                                                       
  8048.         break;                                                                  
  8049.    default:                                                                     
  8050.         fprintf(np->batch_outfile,                                              
  8051.                 "Set of %s failed due to unrecognized var type\n",              
  8052.                 var);                                                           
  8053.  }                                                                              
  8054.  if (bp->runtime_error) {                                                       
  8055.    fprintf(np->batch_outfile,                                                   
  8056.            "Set of %s failed due to errors building value\n",                   
  8057.            var);                                                                
  8058.  }                                                                              
  8059.                                                                                 
  8060.  return;                                                                        
  8061. }                                                                               
  8062.                                                                                 
  8063. /****** Parse batch SET          command. ****************************/         
  8064.                                                                                 
  8065. struct newscmd *                                                                
  8066. NNMbpset(np,bp)                                                                 
  8067. Rstruc nncb         *np;                                                        
  8068. Rstruc batch        *bp;                                                        
  8069. {                                                                               
  8070.  struct newscmd     *cmdp       = NULL;                                         
  8071.  struct ptree       *treep      = NULL;                                         
  8072.  char               *var        = NULL;                                         
  8073.  enum symtype        type;                                                      
  8074.                                                                                 
  8075.  /*                                                                             
  8076.   * Next token must be variable name.                                           
  8077.   */                                                                            
  8078.                                                                                 
  8079.  if (!NNMbgtok(np,bp,TOKEN_READ)) return NULL;   /* get token */                
  8080.  if (bp->curtok.type != WORD_TOKEN) {                                           
  8081.    NNMbsynt(np,bp,NULL,0,                                                       
  8082.             "Expected SET variable name not seen");                             
  8083.    NNMbflus(np,bp);                         /* flush input tokens */            
  8084.    return NULL;                                                                 
  8085.  }                                                                              
  8086.                                                                                 
  8087.  var = NNMcopy(np,bp->curtok.string);                                           
  8088.                                                                                 
  8089.  /*                                                                             
  8090.   * Variable must have been declared, else it is not valid.                     
  8091.   */                                                                            
  8092.                                                                                 
  8093.  if (!(type = (enum symtype)NNMbvget(np,bp,var,NO_SYMTYPE))) {                  
  8094.    NNMbsynt(np,bp,var,0,"Variable has not been declared");                      
  8095.    NNMbflus(np,bp);                         /* flush input tokens */            
  8096.    return NULL;                                                                 
  8097.  }                                                                              
  8098.                                                                                 
  8099.  /*                                                                             
  8100.   * Next token must be either an equal sign or the first of a series            
  8101.   * of "datums".  If the latter, assume the former was present.                 
  8102.   *                                                                             
  8103.   */                                                                            
  8104.                                                                                 
  8105.  if (!NNMbgtok(np,bp,TOKEN_PEEK)) return NULL;   /* Peek next token */          
  8106.  if (bp->nextok.type == EQ_TOKEN) {                                             
  8107.    (void)NNMbgtok(np,bp,TOKEN_FLUSH);            /* Eat the '=' */              
  8108.  }                                                                              
  8109.                                                                                 
  8110.  /*                                                                             
  8111.   * Rest of tokens define the string to which the variable must be set.         
  8112.   * Note that the type (returned by NNMbvget) is the type of the                
  8113.   * variable in question, defining the type of its value.                       
  8114.   */                                                                            
  8115.                                                                                 
  8116.  treep = NNMbgexp(np,bp,type);  /* Get structure describing data */             
  8117.                                                                                 
  8118.  if (treep == NULL) {                                                           
  8119.    NNMbsynt(np,bp,NULL,0,"Bad arguments to SET, need '=' or data");             
  8120.    return NULL;                                                                 
  8121.  }                                                                              
  8122.                                                                                 
  8123.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for SET command");                   
  8124.                                                                                 
  8125.  if (cmdp) {                                                                    
  8126.    cmdp->mode = ANY_MODE;                                                       
  8127.    cmdp->proc = NNMbxset;                                                       
  8128.    cmdp->cmd.scmd.ptreep     = treep;                                           
  8129.    cmdp->cmd.scmd.set_symbol = var;                                             
  8130.    cmdp->cmd.scmd.set_type   = type;                                            
  8131.  }                                                                              
  8132.                                                                                 
  8133.  return cmdp;                                                                   
  8134. }                                                                               
  8135.                                                                                 
  8136. ./   ADD NAME=NNMBPVAR,SSI=01030028                                             
  8137.                                                                                 
  8138.  /********************************************************************/         
  8139.  /*                                                                  */         
  8140.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8141.  /*                                                                  */         
  8142.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8143.  /* including the implied warranties of merchantability and fitness, */         
  8144.  /* are expressly denied.                                            */         
  8145.  /*                                                                  */         
  8146.  /* Provided this copyright notice is included, this software may    */         
  8147.  /* be freely distributed and not offered for sale.                  */         
  8148.  /*                                                                  */         
  8149.  /* Changes or modifications may be made and used only by the maker  */         
  8150.  /* of same, and not further distributed.  Such modifications should */         
  8151.  /* be mailed to the author for consideration for addition to the    */         
  8152.  /* software and incorporation in subsequent releases.               */         
  8153.  /*                                                                  */         
  8154.  /********************************************************************/         
  8155.                                                                                 
  8156. /*=====================================================================         
  8157.  *                                                                              
  8158.  * Command: VARS                                                                
  8159.  *                                                                              
  8160.  * Syntax:  VARS                                                                
  8161.  *                                                                              
  8162.  * Mode:    any                                                                 
  8163.  *                                                                              
  8164.  * Function: Displays all defined variables and their types and values.         
  8165.  *                                                                              
  8166.  * Examples:  VARS                                                              
  8167.  *                                                                              
  8168.  *====================================================================*/        
  8169.                                                                                 
  8170. #pragma  csect(code,  "NN@BPVAR")                                               
  8171. #pragma  csect(static,"NN$BPVAR")                                               
  8172. #include "nn.h"                                                                 
  8173. #include "nnbatch.h"                                                            
  8174.                                                                                 
  8175. /****** Dump variable name, type and value. **************************/         
  8176.                                                                                 
  8177. static void                                                                     
  8178. dump_variable(np,bp,symp)                                                       
  8179. Rstruc nncb         *np;                                                        
  8180. Rstruc batch        *bp;                                                        
  8181. Rstruc symtab       *symp;                                                      
  8182. {                                                                               
  8183.                                                                                 
  8184.  if (!symp) return;                                                             
  8185.                                                                                 
  8186.  fprintf(np->batch_outfile, " %-16.16s  ", symp->symvar);                       
  8187.                                                                                 
  8188.  switch (symp->type) {                                                          
  8189.    case STRING_SYMTYPE:                                                         
  8190.         fprintf(np->batch_outfile, "STRING  %s\n", symp->symval);               
  8191.         break;                                                                  
  8192.    case NUMBER_SYMTYPE:                                                         
  8193.         fprintf(np->batch_outfile, "NUMBER  %d\n", symp->symnum);               
  8194.         break;                                                                  
  8195.    case FLAG_SYMTYPE:                                                           
  8196.         fprintf(np->batch_outfile, "FLAG    %s\n",                              
  8197.                 symp->symnum ? "TRUE" : "FALSE");                               
  8198.         break;                                                                  
  8199.  }                                                                              
  8200.                                                                                 
  8201.  return;                                                                        
  8202. }                                                                               
  8203.                                                                                 
  8204. /****** Display variable. ********************************************/         
  8205.                                                                                 
  8206. static void                                                                     
  8207. display_variable(np,bp,symp)                                                    
  8208. Rstruc nncb         *np;                                                        
  8209. Rstruc batch        *bp;                                                        
  8210. Rstruc symtab       *symp;                                                      
  8211. {                                                                               
  8212.                                                                                 
  8213.  if (!symp) return;                                                             
  8214.                                                                                 
  8215.  if (symp->left) display_variable(np,bp,symp->left);                            
  8216.  dump_variable(np,bp,symp);                                                     
  8217.  if (symp->right) display_variable(np,bp,symp->right);                          
  8218.                                                                                 
  8219.  return;                                                                        
  8220. }                                                                               
  8221.                                                                                 
  8222. /****** Execute batch VARS       command. ****************************/         
  8223.                                                                                 
  8224. static void                                                                     
  8225. NNMbxvar(np,bp,cmdp)                                                            
  8226. Rstruc nncb         *np;                                                        
  8227. Rstruc batch        *bp;                                                        
  8228. Rstruc newscmd      *cmdp;                                                      
  8229. {                                                                               
  8230.                                                                                 
  8231.  fprintf(np->batch_outfile, "Current variables follow\n\n");                    
  8232.                                                                                 
  8233.  display_variable(np,bp,bp->symtabp);                                           
  8234.                                                                                 
  8235.  fprintf(np->batch_outfile, "\nEnd variable display\n");                        
  8236.                                                                                 
  8237.  return;                                                                        
  8238.                                                                                 
  8239. }                                                                               
  8240.                                                                                 
  8241. /****** Parse batch VARS         command. ****************************/         
  8242.                                                                                 
  8243. struct newscmd *                                                                
  8244. NNMbpvar(np,bp)                                                                 
  8245. Rstruc nncb         *np;                                                        
  8246. Rstruc batch        *bp;                                                        
  8247. {                                                                               
  8248.  struct newscmd     *cmdp;                                                      
  8249.                                                                                 
  8250.  bp->stop_at_newline = TRUE;                                                    
  8251.                                                                                 
  8252.  NNMbtras(np,bp,"VARS");   /* Trash extraneous parameters */                    
  8253.                                                                                 
  8254.  if (bp->syntax_error) return NULL;                                             
  8255.                                                                                 
  8256.  GETMAIN(cmdp, struct newscmd, 1, "newscmd for VARS command");                  
  8257.                                                                                 
  8258.  if (cmdp) {                                                                    
  8259.    cmdp->mode = ANY_MODE;                                                       
  8260.    cmdp->proc = NNMbxvar;                                                       
  8261.  }                                                                              
  8262.                                                                                 
  8263.  return cmdp;                                                                   
  8264.                                                                                 
  8265. }                                                                               
  8266.                                                                                 
  8267. ./   ADD NAME=NNMBRIFC,SSI=01310054                                             
  8268.                                                                                 
  8269.  /********************************************************************/         
  8270.  /*                                                                  */         
  8271.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8272.  /*                                                                  */         
  8273.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  8274.  /*                                                                  */         
  8275.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8276.  /* including the implied warranties of merchantability and fitness, */         
  8277.  /* are expressly denied.                                            */         
  8278.  /*                                                                  */         
  8279.  /* Provided this copyright notice is included, this software may    */         
  8280.  /* be freely distributed and not offered for sale.                  */         
  8281.  /*                                                                  */         
  8282.  /* Changes or modifications may be made and used only by the maker  */         
  8283.  /* of same, and not further distributed.  Such modifications should */         
  8284.  /* be mailed to the author for consideration for addition to the    */         
  8285.  /* software and incorporation in subsequent releases.               */         
  8286.  /*                                                                  */         
  8287.  /********************************************************************/         
  8288.                                                                                 
  8289. #pragma  csect(code,  "NN@BRIFC")                                               
  8290. #pragma  csect(static,"NN$BRIFC")                                               
  8291. #include "nn.h"                                                                 
  8292.                                                                                 
  8293. /****** BRIF primary command function. *******************************/         
  8294.                                                                                 
  8295. int                                                                             
  8296. NNMbrifc(numptr,dialog_data_ptr)                                                
  8297. int                  *numptr;                                                   
  8298. void                 *dialog_data_ptr;                                          
  8299. {                                                                               
  8300.  Rstruc nncb         *np = *(Rstruc nncb **)dialog_data_ptr;                    
  8301.  Rstruc newsgroup    *gp = np->current_newsgroup;                               
  8302.  Rstruc newsarticle  *ap = np->article_being_viewed;                            
  8303.  struct newsarticle  *ap1;                                                      
  8304.  char                 zcmd[80];                                                 
  8305.  char                 command[80];                                              
  8306.  char                 operand[80];                                              
  8307.  char                *p;                                                        
  8308.  int                  opoff;                                                    
  8309.                                                                                 
  8310.  /*                                                                             
  8311.   * For commands which are supposed to terminate the current BRIF               
  8312.   * (like NEXT and PREV), we return an invalid return code, which               
  8313.   * is documented to make BRIF itself return with a code of 16,                 
  8314.   * which we treat as a normal end.                                             
  8315.   */                                                                            
  8316.                                                                                 
  8317.  /*                                                                             
  8318.   * Commands:                                                                   
  8319.   *                                                                             
  8320.   *  NEXT - exit this article and display the immediate next one,               
  8321.   *         regardless of its current status                                    
  8322.   *                                                                             
  8323.   *  PREV - exit this article and display the immediate previous one,           
  8324.   *         regardless of its current status                                    
  8325.   *                                                                             
  8326.   *  NEXTS and PREVS - like NEXT and PREV but go to the article that has        
  8327.   *         a matching subject                                                  
  8328.   *                                                                             
  8329.   *  NEXTT and PREVT - like NEXT and PREV but go to the article in the          
  8330.   *         current table or thread                                             
  8331.   *                                                                             
  8332.   *  NEXTU and PREVU - like NEXT and PREV but go to the next or previous        
  8333.   *         unread article                                                      
  8334.   *                                                                             
  8335.   *  FIRSTSUBJ - go to the first article of the same subject                    
  8336.   *                                                                             
  8337.   *  LASTSUBJ - go to the last article of the same subject                      
  8338.   *                                                                             
  8339.   *  NEWSUBJ - go to the first unread article of a different subject            
  8340.   *                                                                             
  8341.   *  SUBJECT - set the subject to something else                                
  8342.   *                                                                             
  8343.   *  UNREAD - mark this article unread and return to the article table          
  8344.   *                                                                             
  8345.   *  QUIT   - terminate NNMVS entirely                                          
  8346.   *                                                                             
  8347.   *  BRIFDEBUG - turn BRIF debugging on and off                                 
  8348.   *                                                                             
  8349.   *  OPTIONS, EXTRACT, PRT, REPLY, FOLLOWUP - do the obvious things             
  8350.   */                                                                            
  8351.                                                                                 
  8352.  (void)NNMivget(np,"ZCMD ",zcmd,sizeof(zcmd));                                  
  8353.  strcpy(command,"");                                                            
  8354.  strcpy(operand,"");                                                            
  8355.  if (1 <= sscanf(zcmd,"%s %n",&command,&opoff)) {                               
  8356.    for (p=command;*p;p++) *p = toupper(*p);                                     
  8357.    if ((EQUAL(command,"EXTRACT") ||  EQUAL(command,"EXT")))  {                  
  8358.      if (!ap) (void)NNMivput(np,"NNTNUM ","",-1);                               
  8359.      np->extract_file = NULL;                                                   
  8360.      (void)NNMispf(np,"CONTROL DISPLAY SAVE");                                  
  8361.      (void)NNMxtx(np,ap,TRUE);                   /* Extract text */             
  8362.      (void)NNMispf(np,"CONTROL DISPLAY RESTORE");                               
  8363.      return 0;                                                                  
  8364.    }                                                                            
  8365.    else                                                                         
  8366.    if (EQUAL(command,"PRT")) {                                                  
  8367.      (void)NNMispf(np,"CONTROL DISPLAY SAVE");                                  
  8368.      NNMptx(np,ap);            /* Print text */                                 
  8369.      (void)NNMispf(np,"CONTROL DISPLAY RESTORE");                               
  8370.      return 0;                                                                  
  8371.    }                                                                            
  8372.    else                                                                         
  8373.    if (EQUAL(command,"QUIT")) {                                                 
  8374.      np->quit = TRUE;                                                           
  8375.      return 1;                                                                  
  8376.    }                                                                            
  8377.    if (EQUAL(command,"BRIFDEBUG")) {                                            
  8378.      if (np->brif_debug) {                                                      
  8379.        np->brif_debug = FALSE;                                                  
  8380.        WARN1("BRIF debugging turned off.  Reissue command to turn on.");        
  8381.      }                                                                          
  8382.      else {                                                                     
  8383.        np->brif_debug = TRUE;                                                   
  8384.        WARN1("BRIF debugging turned on.  Reissue command to turn off.");        
  8385.      }                                                                          
  8386.      return 0;                                                                  
  8387.    }                                                                            
  8388.    else if (ap) {                                                               
  8389.      if (EQUAL(command,"NEXT")) {                                               
  8390.        if (ap >= gp->real_last_article) {                                       
  8391.          ERR1("There are no further articles in this newsgroup.");              
  8392.          np->another_article = NULL;                                            
  8393.          return 12;                                                             
  8394.        }                                                                        
  8395.        np->another_article = ap+1;                                              
  8396.        return 1;                                                                
  8397.      }                                                                          
  8398.      else                                                                       
  8399.      if (EQUAL(command,"PREV")) {                                               
  8400.        if (ap <= gp->first_article) {                                           
  8401.          ERR1("There are no previous articles in this newsgroup.");             
  8402.          np->another_article = NULL;                                            
  8403.          return 12;                                                             
  8404.        }                                                                        
  8405.        np->another_article = ap-1;                                              
  8406.        return 1;                                                                
  8407.      }                                                                          
  8408.      else                                                                       
  8409.      if (EQUAL(command,"NEXTT")                                                 
  8410.       || EQUAL(command,"NT")) {                                                 
  8411.        for (ap1=ap+1; ap1 <= gp->real_last_article; ap1++) {                    
  8412.          if (ArticleInTable(ap1)) {                                             
  8413.            np->another_article = ap1;                                           
  8414.            return 1;                                                            
  8415.          }                                                                      
  8416.        }                                                                        
  8417.        ERR1(                                                                    
  8418. "There are no more news articles that satisfy the current criteria."            
  8419.            );                                                                   
  8420.        np->another_article = NULL;                                              
  8421.        return 12;                                                               
  8422.      }                                                                          
  8423.      else                                                                       
  8424.      if (EQUAL(command,"PREVT")                                                 
  8425.       || EQUAL(command,"PT")) {                                                 
  8426.        for (ap1=ap-1; ap1 >= gp->first_article; ap1--) {                        
  8427.          if (ArticleInTable(ap1)) {                                             
  8428.            np->another_article = ap1;                                           
  8429.            return 1;                                                            
  8430.          }                                                                      
  8431.        }                                                                        
  8432.        ERR1(                                                                    
  8433. "There are no previous news articles that satisfy the current criteria."        
  8434.            );                                                                   
  8435.        np->another_article = NULL;                                              
  8436.        return 12;                                                               
  8437.      }                                                                          
  8438.      else                                                                       
  8439.      if (EQUAL(command,"NEXTU")                                                 
  8440.       || EQUAL(command,"NU")) {                                                 
  8441.        for (ap1=ap+1; ap1 <= gp->real_last_article; ap1++) {                    
  8442.          if (V_STATUS(gp,ap1->number) == V_UNREAD) {                            
  8443.            np->another_article = ap1;                                           
  8444.            return 1;                                                            
  8445.          }                                                                      
  8446.        }                                                                        
  8447.        ERR1("There are no further unread articles in this newsgroup.");         
  8448.        np->another_article = NULL;                                              
  8449.        return 12;                                                               
  8450.      }                                                                          
  8451.      else                                                                       
  8452.      if (EQUAL(command,"PREVU")                                                 
  8453.       || EQUAL(command,"PU")) {                                                 
  8454.        for (ap1=ap-1; ap1 >= gp->first_article; ap1--) {                        
  8455.          if (V_STATUS(gp,ap1->number) == V_UNREAD) {                            
  8456.            np->another_article = ap1;                                           
  8457.            return 1;                                                            
  8458.          }                                                                      
  8459.        }                                                                        
  8460.        ERR1("There are no previous unread articles in this newsgroup.");        
  8461.        np->another_article = NULL;                                              
  8462.        return 12;                                                               
  8463.      }                                                                          
  8464.      else                                                                       
  8465.      if (EQUAL(command,"UNREAD")) {                                             
  8466.        np->another_article = (struct newsarticle *)UNREAD_THIS_ARTICLE;         
  8467.        return 1;                                                                
  8468.      }                                                                          
  8469.      else                                                                       
  8470.      if (EQUAL(command,"NEXTS")                                                 
  8471.       || EQUAL(command,"NEXTSUBJ")                                              
  8472.       || EQUAL(command,"NS")) {                                                 
  8473.        np->another_article = (struct newsarticle *)NEXT_THREAD_ARTICLE;         
  8474.        return 1;                                                                
  8475.      }                                                                          
  8476.      else                                                                       
  8477.      if (EQUAL(command,"PREVS")                                                 
  8478.       || EQUAL(command,"PREVSUBJ")                                              
  8479.       || EQUAL(command,"PS")) {                                                 
  8480.        np->another_article = (struct newsarticle *)PREV_THREAD_ARTICLE;         
  8481.        return 1;                                                                
  8482.      }                                                                          
  8483.      else                                                                       
  8484.      if (EQUAL(command,"FIRSTS")                                                
  8485.       || EQUAL(command,"FIRSTSUBJ")                                             
  8486.       || EQUAL(command,"FS")) {                                                 
  8487.        np->another_article = (struct newsarticle *)FIRST_THREAD_ARTICLE;        
  8488.        return 1;                                                                
  8489.      }                                                                          
  8490.      else                                                                       
  8491.      if (EQUAL(command,"LASTS")                                                 
  8492.       || EQUAL(command,"LASTSUBJ")                                              
  8493.       || EQUAL(command,"LS")) {                                                 
  8494.        np->another_article = (struct newsarticle *)LAST_THREAD_ARTICLE;         
  8495.        return 1;                                                                
  8496.      }                                                                          
  8497.      else                                                                       
  8498.      if (EQUAL(command,"NEWSUBJ")) {                                            
  8499.        np->another_article = (struct newsarticle *)NEW_THREAD_ARTICLE;          
  8500.        return 1;                                                                
  8501.      }                                                                          
  8502.      else                                                                       
  8503.      if (EQUAL(command,"SUBJECT")                                               
  8504.       || EQUAL(command,"SUBJ")) {                                               
  8505.                                                                                 
  8506.      /* If anything remaining on the command line, make it the new    */        
  8507.      /* subject, otherwise just display the current subject.          */        
  8508.                                                                                 
  8509.        p = zcmd + opoff;                                                        
  8510.        if (*p) {                                                                
  8511.          memset(np->selsubj,0,sizeof(np->selsubj));                             
  8512.          strncpy(np->selsubj,p,sizeof(np->selsubj)-1);                          
  8513.          WARN1(                                                                 
  8514.    "Subject changed.  All subject searches will use the new subject.");         
  8515.        }                                                                        
  8516.        else if (!*np->selsubj) {                                                
  8517.          WARN1(                                                                 
  8518.      "No current subject has been set by a subject-related command.");          
  8519.        }                                                                        
  8520.        else {                                                                   
  8521.          WARN2("Current subject: %s", np->selsubj);                             
  8522.        }                                                                        
  8523.        return 0;                                                                
  8524.      }                                                                          
  8525.      else                                                                       
  8526.      if (EQUAL(command,"REPLY")) {                                              
  8527.        (void)NNMispf(np,"CONTROL DISPLAY SAVE");                                
  8528.        NNMdmail(np,gp,ap);       /* Send mail message */                        
  8529.        (void)NNMispf(np,"CONTROL DISPLAY RESTORE");                             
  8530.        return 0;                                                                
  8531.      }                                                                          
  8532.      else                                                                       
  8533.      if (EQUAL(command,"FOLLOWUP")) {                                           
  8534.        (void)NNMispf(np,"CONTROL DISPLAY SAVE");                                
  8535.        NNMdpost(np,gp,ap);       /* Post followup */                            
  8536.        (void)NNMispf(np,"CONTROL DISPLAY RESTORE");                             
  8537.        return 0;                                                                
  8538.      }                                                                          
  8539.      else                                                                       
  8540.      if (EQUAL(command,"OPTIONS") || EQUAL(command,"OPT")) {                    
  8541.        sscanf(zcmd+opoff,"%s",&operand);                                        
  8542.        NNMdsopt(np,operand);         /* Do "set options" function */            
  8543.        np->another_article = ap;                                                
  8544.        return 1;                                                                
  8545.      }                                                                          
  8546.      else                                                                       
  8547.      if (EQUAL(command,"HEADERS") || EQUAL(command,"HEADER")) {                 
  8548.        NNMdsopt(np,"1");             /* Do "set options 1" function */          
  8549.        np->another_article = ap;                                                
  8550.        return 1;                                                                
  8551.      }                                                                          
  8552.      else {                                                                     
  8553.        ERR1(                                                                    
  8554. "What? Try: NEXT/PREV{,S,T,U} EXTract UNREAD OPTions REPLY FOLLOWUP..."         
  8555.            );                                                                   
  8556.        return 12;                                                               
  8557.      }                                                                          
  8558.    }                                                                            
  8559.    else {                                                                       
  8560.      ERR1(                                                                      
  8561. "The only non-BROWSE commands are EXTract, PRT and QUIT."                       
  8562.          );                                                                     
  8563.      return 12;                                                                 
  8564.    }                                                                            
  8565.  }                                                                              
  8566.                                                                                 
  8567.  return 4; /* ISPF-PDF should handle the command */                             
  8568.                                                                                 
  8569. }                                                                               
  8570.                                                                                 
  8571. ./   ADD NAME=NNMBRIFR,SSI=01040000                                             
  8572.                                                                                 
  8573.  /********************************************************************/         
  8574.  /*                                                                  */         
  8575.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8576.  /*                                                                  */         
  8577.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8578.  /* including the implied warranties of merchantability and fitness, */         
  8579.  /* are expressly denied.                                            */         
  8580.  /*                                                                  */         
  8581.  /* Provided this copyright notice is included, this software may    */         
  8582.  /* be freely distributed and not offered for sale.                  */         
  8583.  /*                                                                  */         
  8584.  /* Changes or modifications may be made and used only by the maker  */         
  8585.  /* of same, and not further distributed.  Such modifications should */         
  8586.  /* be mailed to the author for consideration for addition to the    */         
  8587.  /* software and incorporation in subsequent releases.               */         
  8588.  /*                                                                  */         
  8589.  /********************************************************************/         
  8590.                                                                                 
  8591. #pragma  csect(code,  "NN@BRIFR")                                               
  8592. #pragma  csect(static,"NN$BRIFR")                                               
  8593. #include "nn.h"                                                                 
  8594.                                                                                 
  8595. /****** BRIF read function. ******************************************/         
  8596.                                                                                 
  8597. int                                                                             
  8598. NNMbrifr(dataptr,lenptr,recnoptr,dialog_data_ptr)                               
  8599. char                **dataptr;                                                  
  8600. int                  *lenptr;                                                   
  8601. int                  *recnoptr;                                                 
  8602. void                 *dialog_data_ptr;                                          
  8603. {                                                                               
  8604.  Rstruc textline     *tp;                                                       
  8605.  Rstruc nncb         *np;                                                       
  8606.  Rstruc texthdr      *thp;                                                      
  8607.         int           return_value;                                             
  8608.         int           current_recno;                                            
  8609.         int           i;                                                        
  8610.                                                                                 
  8611.  np             = *(struct nncb **)dialog_data_ptr;                             
  8612.  thp            = np->brifp;                                                    
  8613.  current_recno  = *recnoptr;                                                    
  8614.  return_value   = 0;                                                            
  8615.  tp             = NULL;                                                         
  8616.                                                                                 
  8617.  if (np->brif_debug) {                                                          
  8618.    fprintf(stderr,"BRIF_DEBUG: requested recno = %d\n",current_recno);          
  8619.  }                                                                              
  8620.                                                                                 
  8621.  if (current_recno == 99999999) {    /* scroll down max request */              
  8622.    tp = NULL;                                                                   
  8623.  }                                                                              
  8624.  else if (thp->current_text_line != NULL &&                                     
  8625.           current_recno == np->brif_previous_recno+1) {                         
  8626.    if (np->brif_debug) {                                                        
  8627.      fprintf(stderr,"BRIF_DEBUG: matches previous record + 1 (win)\n");         
  8628.    }                                                                            
  8629.    tp = thp->current_text_line->next;                                           
  8630.    while (tp && tp->text_length < 0) tp = tp->next;                             
  8631.  }                                                                              
  8632.  else {                                                                         
  8633.    if (np->brif_debug) {                                                        
  8634.      fprintf(stderr,"BRIF_DEBUG: must search for this record (lose)\n");        
  8635.    }                                                                            
  8636.    for (i = 0, tp = thp->first_text_line; tp; tp = tp->next) {                  
  8637.      if (tp->text_length >= 0) {                                                
  8638.        if (++i >= current_recno) break;                                         
  8639.      }                                                                          
  8640.    }                                                                            
  8641.  }                                                                              
  8642.                                                                                 
  8643.  if (tp == NULL) {                                                              
  8644.    *recnoptr = thp->text_line_count;                                            
  8645.    return_value = 8;                                                            
  8646.  }                                                                              
  8647.  else {                                                                         
  8648.    thp->current_text_line = tp;                                                 
  8649.    *dataptr = tp->tab_expanded_text;                                            
  8650.    *lenptr  = tp->tab_expanded_text_length;                                     
  8651.    return_value = 0;                                                            
  8652.  }                                                                              
  8653.                                                                                 
  8654.  np->brif_previous_recno = current_recno;                                       
  8655.                                                                                 
  8656.  if (np->brif_debug) {                                                          
  8657.    fprintf(stderr,"BRIF_DEBUG: returning recno = %d\n",current_recno);          
  8658.    fprintf(stderr,"BRIF_DEBUG: return value    = %d\n\n",return_value);         
  8659.  }                                                                              
  8660.                                                                                 
  8661.  return return_value;                                                           
  8662.                                                                                 
  8663. }                                                                               
  8664.                                                                                 
  8665. ./   ADD NAME=NNMBSOUT,SSI=01080029                                             
  8666.                                                                                 
  8667.  /********************************************************************/         
  8668.  /*                                                                  */         
  8669.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8670.  /*                                                                  */         
  8671.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8672.  /* including the implied warranties of merchantability and fitness, */         
  8673.  /* are expressly denied.                                            */         
  8674.  /*                                                                  */         
  8675.  /* Provided this copyright notice is included, this software may    */         
  8676.  /* be freely distributed and not offered for sale.                  */         
  8677.  /*                                                                  */         
  8678.  /* Changes or modifications may be made and used only by the maker  */         
  8679.  /* of same, and not further distributed.  Such modifications should */         
  8680.  /* be mailed to the author for consideration for addition to the    */         
  8681.  /* software and incorporation in subsequent releases.               */         
  8682.  /*                                                                  */         
  8683.  /********************************************************************/         
  8684.                                                                                 
  8685. #pragma  csect(code,  "NN@BSOUT")                                               
  8686. #pragma  csect(static,"NN$BSOUT")                                               
  8687. #include "nn.h"                                                                 
  8688. #include "nnbatch.h"                                                            
  8689.                                                                                 
  8690. /****** Set the output file from the OUTFILE variable. ***************/         
  8691.                                                                                 
  8692. FILE *                                                                          
  8693. NNMbsout(np,bp)                                                                 
  8694. Rstruc nncb         *np;                                                        
  8695. Rstruc batch        *bp;                                                        
  8696. {                                                                               
  8697.  char               *outfile;                                                   
  8698.  char               *openmode;                                                  
  8699.  FILE               *outfp = NULL;                                              
  8700.  FILE               *infp  = NULL;                                              
  8701.                                                                                 
  8702.  outfile = GETC("OUTFILE");                                                     
  8703.  if (!outfile) outfile = "";                                                    
  8704.  if (bp->outfilename && EQUAL(bp->outfilename,outfile)) {                       
  8705.    if (!bp->outfp) outfp = np->batch_outfile;                                   
  8706.    else outfp = bp->outfp;                                                      
  8707.  }                                                                              
  8708.  else {                                                                         
  8709.    if (bp->outfp) {                                                             
  8710.      if (fclose(bp->outfp) < 0) {                                               
  8711.        fprintf(stderr,"Error closing outfile\n");                               
  8712.        bp->runtime_error = TRUE;                                                
  8713.      }                                                                          
  8714.      fprintf(np->batch_outfile,"Ending output to %s\n",                         
  8715.              bp->outfilename);                                                  
  8716.      bp->outfp = NULL;                                                          
  8717.      bp->outfilename = NULL;                                                    
  8718.    }                                                                            
  8719.    if (*outfile) {                                                              
  8720.      infp = fopen(outfile,"r");  /* If file exists, append to it. */            
  8721.      if (infp) {                                                                
  8722.        openmode = "a";                                                          
  8723.        fclose(infp);                                                            
  8724.      }                                                                          
  8725.      else {                                                                     
  8726.        openmode = "w,recfm=vb,lrecl=259,blksize=6233";                          
  8727.      }                                                                          
  8728.      outfp = fopen(outfile,openmode);                                           
  8729.      if (!outfp) {                                                              
  8730.        perror(outfile);                                                         
  8731.        fprintf(np->batch_outfile,"Error: OUTFILE %s is not usable.\n",          
  8732.                                  outfile);                                      
  8733.        bp->runtime_error = TRUE;                                                
  8734.      }                                                                          
  8735.      else {                                                                     
  8736.        bp->outfp = outfp;                                                       
  8737.        bp->outfilename = NNMcopy(np,outfile);                                   
  8738.        fprintf(np->batch_outfile,"Beginning output to %s\n",                    
  8739.                                  outfile);                                      
  8740.      }                                                                          
  8741.    }                                                                            
  8742.    else {                                                                       
  8743.      outfp = np->batch_outfile;                                                 
  8744.      bp->outfp = NULL;                                                          
  8745.      bp->outfilename = NULL;                                                    
  8746.    }                                                                            
  8747.  }                                                                              
  8748.                                                                                 
  8749.  return outfp;                                                                  
  8750. }                                                                               
  8751.                                                                                 
  8752. ./   ADD NAME=NNMBSYNT,SSI=01040047                                             
  8753.                                                                                 
  8754.  /********************************************************************/         
  8755.  /*                                                                  */         
  8756.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8757.  /*                                                                  */         
  8758.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8759.  /* including the implied warranties of merchantability and fitness, */         
  8760.  /* are expressly denied.                                            */         
  8761.  /*                                                                  */         
  8762.  /* Provided this copyright notice is included, this software may    */         
  8763.  /* be freely distributed and not offered for sale.                  */         
  8764.  /*                                                                  */         
  8765.  /* Changes or modifications may be made and used only by the maker  */         
  8766.  /* of same, and not further distributed.  Such modifications should */         
  8767.  /* be mailed to the author for consideration for addition to the    */         
  8768.  /* software and incorporation in subsequent releases.               */         
  8769.  /*                                                                  */         
  8770.  /********************************************************************/         
  8771.                                                                                 
  8772. #pragma  csect(code,  "NN@BSYNT")                                               
  8773. #pragma  csect(static,"NN$BSYNT")                                               
  8774. #include "nn.h"                                                                 
  8775. #include "nnbatch.h"                                                            
  8776.                                                                                 
  8777. /****** Syntax error. ************************************************/         
  8778.                                                                                 
  8779. void                                                                            
  8780. NNMbsynt(np,bp,cp,len,msg)                                                      
  8781. Rstruc nncb         *np;                                                        
  8782. Rstruc batch        *bp;                                                        
  8783. char                *cp;                                                        
  8784. int                  len;                                                       
  8785. char                *msg;                                                       
  8786. {                                                                               
  8787.                                                                                 
  8788.  if (cp && len == 0) len = strlen(cp);                                          
  8789.  if (!cp) {                                                                     
  8790.    fprintf(np->batch_outfile, "Syntax error: %s.\n", msg);                      
  8791.  }                                                                              
  8792.  else {                                                                         
  8793.    fprintf(np->batch_outfile, "Syntax error: %s.  Token: %*.*s\n",              
  8794.                               msg, len, len, cp);                               
  8795.  }                                                                              
  8796.                                                                                 
  8797.  bp->syntax_error = TRUE;                                                       
  8798.  bp->curtok.type  = ERROR_TOKEN;                                                
  8799.  bp->nextok.type  = NO_TOKEN;                                                   
  8800.  bp->input_errors++;                                                            
  8801.                                                                                 
  8802.  return;                                                                        
  8803. }                                                                               
  8804.                                                                                 
  8805. ./   ADD NAME=NNMBTEXT,SSI=01130006                                             
  8806.                                                                                 
  8807.  /********************************************************************/         
  8808.  /*                                                                  */         
  8809.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8810.  /*                                                                  */         
  8811.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8812.  /* including the implied warranties of merchantability and fitness, */         
  8813.  /* are expressly denied.                                            */         
  8814.  /*                                                                  */         
  8815.  /* Provided this copyright notice is included, this software may    */         
  8816.  /* be freely distributed and not offered for sale.                  */         
  8817.  /*                                                                  */         
  8818.  /* Changes or modifications may be made and used only by the maker  */         
  8819.  /* of same, and not further distributed.  Such modifications should */         
  8820.  /* be mailed to the author for consideration for addition to the    */         
  8821.  /* software and incorporation in subsequent releases.               */         
  8822.  /*                                                                  */         
  8823.  /********************************************************************/         
  8824.                                                                                 
  8825. #pragma  csect(code,  "NN@BTEXT")                                               
  8826. #pragma  csect(static,"NN$BTEXT")                                               
  8827. #include "nn.h"                                                                 
  8828. #include "nnbatch.h"                                                            
  8829.                                                                                 
  8830. /****** Print text lines. ********************************************/         
  8831.                                                                                 
  8832. static int                                                                      
  8833. print_text_lines(np,bp,fp,textp,linep,extracting)                               
  8834. Rstruc nncb         *np;                                                        
  8835. Rstruc batch        *bp;                                                        
  8836. FILE                *fp;                                                        
  8837. struct textline     *textp;                                                     
  8838. char               **linep;                                                     
  8839. Fool                 extracting;                                                
  8840. {                                                                               
  8841.  struct textline    *tp;                                                        
  8842.  char               *cp;                                                        
  8843.  int                 l;                                                         
  8844.  int                 write_error;                                               
  8845.  Bool                tab_expanding;                                             
  8846.  Bool                appending;                                                 
  8847.  Bool                blank_before_separator;                                    
  8848.  char               *separator_line;                                            
  8849.                                                                                 
  8850.  if (!fp) return TRUE;                                                          
  8851.                                                                                 
  8852.  /*                                                                             
  8853.   *  char               *p;                                                     
  8854.   *                                                                             
  8855.   *  for (tp=textp; tp; tp=tp->next) {                                          
  8856.   *    if (tp->text_length >= 0) {                                              
  8857.   *      p = tp->tab_expanded_text;                                             
  8858.   *      while (*p) {                                                           
  8859.   *        if isprint(*p) fprintf(fp,"%c",*p);                                  
  8860.   *        else fprintf(fp,"?");                                                
  8861.   *        p++;                                                                 
  8862.   *      }                                                                      
  8863.   *      fprintf(fp,"\n");                                                      
  8864.   *    }                                                                        
  8865.   *  }                                                                          
  8866.   *  fprintf(fp,"\n");                                                          
  8867.   */                                                                            
  8868.                                                                                 
  8869.  if (extracting) {                                                              
  8870.    tab_expanding           = np->extract_tab_expanding;                         
  8871.    appending               = np->extract_appending;                             
  8872.    blank_before_separator  = np->extract_blank_before_separator;                
  8873.    separator_line          = np->extract_separator_line;                        
  8874.  }                                                                              
  8875.  else {                                                                         
  8876.    tab_expanding           = TRUE;                                              
  8877.    appending               = FALSE;                                             
  8878.    blank_before_separator  = FALSE;                                             
  8879.    separator_line          = "";                                                
  8880.  }                                                                              
  8881.                                                                                 
  8882.  tab_expanding = extracting ? np->extract_tab_expanding                         
  8883.                             : GETB("TABEXPAND");                                
  8884.  write_error   = 0;                                                             
  8885.                                                                                 
  8886.  /* If append mode, and a separator line was specified, use it. */              
  8887.                                                                                 
  8888.  while (appending && separator_line && *separator_line) {                       
  8889.    if (fprintf(fp,"%s\n",separator_line) < 0) {                                 
  8890.      *linep = separator_line;                                                   
  8891.      write_error = 1;                                                           
  8892.      break;                                                                     
  8893.    }                                                                            
  8894.    if (blank_before_separator) {                                                
  8895.      if (fprintf(fp,"\n") < 0) {                                                
  8896.        *linep = "<blank before separator>";                                     
  8897.        write_error = 2;                                                         
  8898.        break;                                                                   
  8899.      }                                                                          
  8900.    }                                                                            
  8901.    break;                                                                       
  8902.  }                                                                              
  8903.                                                                                 
  8904.  for (tp=textp;                                                                 
  8905.       tp && !write_error;                                                       
  8906.       tp=tp->next) {                                                            
  8907.    if (tp->text_length == 0) {                                                  
  8908.      if (fputc('\n',fp) == EOF) {                                               
  8909.        *linep = "<single newline character>";                                   
  8910.        write_error = 3;                                                         
  8911.        break;                                                                   
  8912.      }                                                                          
  8913.    }                                                                            
  8914.    else if (tp->text_length > 0) {                                              
  8915.      if (tab_expanding) {                                                       
  8916.        cp = tp->tab_expanded_text;                                              
  8917.        l  = tp->tab_expanded_text_length;                                       
  8918.      }                                                                          
  8919.      else {                                                                     
  8920.        cp = tp->text;                                                           
  8921.        l  = tp->text_length;                                                    
  8922.      }                                                                          
  8923.      for (; l > 0; cp += 251, l -= 251) {                                       
  8924.        fwrite(cp,(l>251 ? 251 : l),1,fp);                                       
  8925.        if (ferror(fp)) {                                                        
  8926.          *linep = cp;                                                           
  8927.          write_error = 4;                                                       
  8928.          break;                                                                 
  8929.        }                                                                        
  8930.        if (fputc('\n',fp) == EOF) {                                             
  8931.          *linep = "<single newline character>";                                 
  8932.          write_error = 5;                                                       
  8933.          break;                                                                 
  8934.        }                                                                        
  8935.      }                                                                          
  8936.    }                                                                            
  8937.  }                                                                              
  8938.                                                                                 
  8939.  if (write_error) return write_error;                                           
  8940.  if (ferror(fp)) {                                                              
  8941.    *linep = "<ferror occurred>";                                                
  8942.    return -1;                                                                   
  8943.  }                                                                              
  8944.  else return 0;                                                                 
  8945. }                                                                               
  8946.                                                                                 
  8947. /****** Process the lines of text retrieved from server. *************/         
  8948.                                                                                 
  8949. void                                                                            
  8950. NNMbtext(np,thp,fp)                                                             
  8951. Rstruc nncb         *np;                                                        
  8952. struct texthdr      *thp;                                                       
  8953. FILE                *fp;                                                        
  8954. {                                                                               
  8955.  Rstruc batch       *bp = np->batch_hook;                                       
  8956.  int                 rc;                                                        
  8957.  char               *line;                                                      
  8958.  Fool                extracting;                                                
  8959.                                                                                 
  8960.  if (fp) {  /* file pointer passed :: called from EXTRACT command */            
  8961.    extracting = TRUE;                                                           
  8962.  }                                                                              
  8963.  else {                                                                         
  8964.    fp = NNMbsout(np,bp);    /* set output file */                               
  8965.    extracting = FALSE;                                                          
  8966.  }                                                                              
  8967.                                                                                 
  8968.  rc = print_text_lines(np,bp,fp,thp->first_text_line,&line,extracting);         
  8969.  if (rc != 0) {                                                                 
  8970.    fprintf(stderr,"Error %d writing text to outfile\n",rc);                     
  8971.    fprintf(stderr,"Line: %s\n",line);                                           
  8972.    bp->runtime_error = TRUE;                                                    
  8973.  }                                                                              
  8974.                                                                                 
  8975.  return;                                                                        
  8976.                                                                                 
  8977. }                                                                               
  8978.                                                                                 
  8979. ./   ADD NAME=NNMBTRAS,SSI=01030023                                             
  8980.                                                                                 
  8981.  /********************************************************************/         
  8982.  /*                                                                  */         
  8983.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  8984.  /*                                                                  */         
  8985.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  8986.  /* including the implied warranties of merchantability and fitness, */         
  8987.  /* are expressly denied.                                            */         
  8988.  /*                                                                  */         
  8989.  /* Provided this copyright notice is included, this software may    */         
  8990.  /* be freely distributed and not offered for sale.                  */         
  8991.  /*                                                                  */         
  8992.  /* Changes or modifications may be made and used only by the maker  */         
  8993.  /* of same, and not further distributed.  Such modifications should */         
  8994.  /* be mailed to the author for consideration for addition to the    */         
  8995.  /* software and incorporation in subsequent releases.               */         
  8996.  /*                                                                  */         
  8997.  /********************************************************************/         
  8998.                                                                                 
  8999. #pragma  csect(code,  "NN@BTRAS")                                               
  9000. #pragma  csect(static,"NN$BTRAS")                                               
  9001. #include "nn.h"                                                                 
  9002. #include "nnbatch.h"                                                            
  9003.                                                                                 
  9004. /****** Trash extraneous data in command line. ***********************/         
  9005.                                                                                 
  9006. void                                                                            
  9007. NNMbtras(np,bp,name)                                                            
  9008. Rstruc nncb         *np;                                                        
  9009. Rstruc batch        *bp;                                                        
  9010. char                *name;                                                      
  9011. {                                                                               
  9012.  struct token       *tp;                                                        
  9013.  Bool                finished = FALSE;                                          
  9014.  char                temp[81];                                                  
  9015.                                                                                 
  9016.  /*                                                                             
  9017.   * Pull tokens until semicolon or EOF.  Note that EOL will not be              
  9018.   * considered the end of the datum stream, because the user may wish           
  9019.   * to specify a long list that takes several lines.  Therefore, an             
  9020.   * explicit semicolon is required to terminate the list.                       
  9021.   */                                                                            
  9022.                                                                                 
  9023.  while (!finished && (tp = PEEK())) {                                           
  9024.    switch (tp->type) {                                                          
  9025.      case EOL_TOKEN:                                                            
  9026.      case EOF_TOKEN:                                                            
  9027.      case SEMI_TOKEN:   EAT();                                                  
  9028.                         finished = TRUE;                                        
  9029.                         break;                                                  
  9030.      default:           EAT();                                                  
  9031.                         sprintf(temp,"Extraneous data in %s command",           
  9032.                                      name);                                     
  9033.                         NNMbsynt(np,bp,tp->string,0,temp);                      
  9034.                         break;                                                  
  9035.    }                                                                            
  9036.  }                                                                              
  9037.                                                                                 
  9038.  return;                                                                        
  9039. }                                                                               
  9040.                                                                                 
  9041. ./   ADD NAME=NNMBVGET,SSI=01140019                                             
  9042.                                                                                 
  9043.  /********************************************************************/         
  9044.  /*                                                                  */         
  9045.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  9046.  /*                                                                  */         
  9047.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  9048.  /* including the implied warranties of merchantability and fitness, */         
  9049.  /* are expressly denied.                                            */         
  9050.  /*                                                                  */         
  9051.  /* Provided this copyright notice is included, this software may    */         
  9052.  /* be freely distributed and not offered for sale.                  */         
  9053.  /*                                                                  */         
  9054.  /* Changes or modifications may be made and used only by the maker  */         
  9055.  /* of same, and not further distributed.  Such modifications should */         
  9056.  /* be mailed to the author for consideration for addition to the    */         
  9057.  /* software and incorporation in subsequent releases.               */         
  9058.  /*                                                                  */         
  9059.  /********************************************************************/         
  9060.                                                                                 
  9061. #pragma  csect(code,  "NN@BVGET")                                               
  9062. #pragma  csect(static,"NN$BVGET")                                               
  9063. #include "nn.h"                                                                 
  9064. #include "nnbatch.h"                                                            
  9065.                                                                                 
  9066. /****** Report type mismatch error. **********************************/         
  9067.                                                                                 
  9068. static void                                                                     
  9069. type_error(np,var,type1,type2)                                                  
  9070. Rstruc nncb     *np;                                                            
  9071. char            *var;                                                           
  9072. char            *type1;                                                         
  9073. char            *type2;                                                         
  9074. {                                                                               
  9075.                                                                                 
  9076.  ERR4("Type mismatch: \                                                         
  9077. Cannot retrieve a value of type %s from %s variable %s.",                       
  9078.       type1,type2,var);                                                         
  9079.                                                                                 
  9080.  return;                                                                        
  9081.                                                                                 
  9082. }                                                                               
  9083.                                                                                 
  9084. /****** Get a value from the symbol table. ***************************/         
  9085.                                                                                 
  9086. ANYTYPE                                                                         
  9087. NNMbvget(np,bp,var,type)                                                        
  9088. Rstruc nncb         *np;                                                        
  9089. Rstruc batch        *bp;                                                        
  9090. char                *var;                                                       
  9091. enum symtype         type;                                                      
  9092. {                                                                               
  9093.  Rstruc symtab      *symp;                                                      
  9094.  int                 varlen;                                                    
  9095.  char                vartest[MAX_SYMBOL_LENGTH];                                
  9096.                                                                                 
  9097.  varlen = strlen(var);                                                          
  9098.  if (varlen < 1 || varlen > MAX_SYMBOL_LENGTH) {                                
  9099.    ERR2(                                                                        
  9100.     "A variable name must be between 1 and %d characters in length.",           
  9101.         MAX_SYMBOL_LENGTH);                                                     
  9102.    return FALSE;                                                                
  9103.  }                                                                              
  9104.                                                                                 
  9105.  memset(vartest,'\0',MAX_SYMBOL_LENGTH);                                        
  9106.  memcpy(vartest,var,varlen);                                                    
  9107.                                                                                 
  9108.  symp = bp->symtabp;                                                            
  9109.                                                                                 
  9110.  while (symp) {                                                                 
  9111.    switch (memcmp(vartest, symp->symvar, MAX_SYMBOL_LENGTH)) {                  
  9112.      case 0:   /* equal   */                                                    
  9113.                break;                                                           
  9114.      case 1:   /* greater */                                                    
  9115.                symp = symp->right;                                              
  9116.                continue;                                                        
  9117.      default:  /* less    */                                                    
  9118.                symp = symp->left;                                               
  9119.                continue;                                                        
  9120.    }                                                                            
  9121.    break;                                                                       
  9122.  }                                                                              
  9123.                                                                                 
  9124.  /* Special case, just to see if the variable exists or not. */                 
  9125.                                                                                 
  9126.  if (type == NO_SYMTYPE)                                                        
  9127.     return (symp ? (ANYTYPE)symp->type : (ANYTYPE)NO_SYMTYPE);                  
  9128.                                                                                 
  9129.  if (!symp) {                                                                   
  9130.    ERR2("The variable %s has not been declared or set to a value.",             
  9131.         var);                                                                   
  9132.    return NULL;                                                                 
  9133.  }                                                                              
  9134.                                                                                 
  9135.  /*------------------------------------------------------------------*          
  9136.   *                                                                  *          
  9137.   * Table of allowable type-to-type settings:                        *          
  9138.   *                                                                  *          
  9139.   * symp->type |   type      | result                                *          
  9140.   *____________|_____________|_________________________________      *          
  9141.   * STRING     |   STRING    | OK                                    *          
  9142.   *            |   NUMBER    | error                                 *          
  9143.   *            |   FLAG      | error                                 *          
  9144.   *____________|_____________|_________________________________      *          
  9145.   * NUMBER     |   STRING    | convert to string via sprintf %d      *          
  9146.   *            |   NUMBER    | OK                                    *          
  9147.   *            |   FLAG      | interpret as nonzero or zero          *          
  9148.   *____________|_____________|_________________________________      *          
  9149.   * FLAG       |   STRING    | convert to "1" or "0"                 *          
  9150.   *            |   NUMBER    | convert to 1 or 0                     *          
  9151.   *            |   FLAG      | OK                                    *          
  9152.   *            |             |                                       *          
  9153.   *------------------------------------------------------------------*/         
  9154.                                                                                 
  9155.  switch (symp->type) {                                                          
  9156.    case STRING_SYMTYPE:                                                         
  9157.         switch (type) {                                                         
  9158.           case STRING_SYMTYPE: return (ANYTYPE)symp->symval;                    
  9159.                                                                                 
  9160.           case NUMBER_SYMTYPE: type_error(np,var,"NUMBER","STRING");            
  9161.                                break;                                           
  9162.           case FLAG_SYMTYPE:   type_error(np,var,"FLAG","STRING");              
  9163.                                break;                                           
  9164.         }                                                                       
  9165.         break;                                                                  
  9166.    case NUMBER_SYMTYPE:                                                         
  9167.         switch (type) {                                                         
  9168.           case STRING_SYMTYPE: sprintf(symp->symval,"%d",symp->symnum);         
  9169.                                return (ANYTYPE)symp->symval;                    
  9170.                                                                                 
  9171.           case NUMBER_SYMTYPE: return (ANYTYPE)symp->symnum;                    
  9172.                                                                                 
  9173.           case FLAG_SYMTYPE:   return (symp->symnum                             
  9174.                                        ? (ANYTYPE)1 : (ANYTYPE)0);              
  9175.                                                                                 
  9176.         }                                                                       
  9177.         break;                                                                  
  9178.    case FLAG_SYMTYPE:                                                           
  9179.         switch (type) {                                                         
  9180.           case STRING_SYMTYPE: return (symp->symnum                             
  9181.                                        ? (ANYTYPE)"1" : (ANYTYPE)"0");          
  9182.                                                                                 
  9183.           case NUMBER_SYMTYPE: return (symp->symnum                             
  9184.                                        ? (ANYTYPE)1 : (ANYTYPE)0);              
  9185.                                                                                 
  9186.           case FLAG_SYMTYPE:   return (symp->symnum                             
  9187.                                        ? (ANYTYPE)1 : (ANYTYPE)0);              
  9188.                                                                                 
  9189.         }                                                                       
  9190.         break;                                                                  
  9191.  }                                                                              
  9192.                                                                                 
  9193.  return NULL;                                                                   
  9194. }                                                                               
  9195.                                                                                 
  9196. ./   ADD NAME=NNMBVPUT,SSI=011C0011                                             
  9197.                                                                                 
  9198.  /********************************************************************/         
  9199.  /*                                                                  */         
  9200.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  9201.  /*                                                                  */         
  9202.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  9203.  /* including the implied warranties of merchantability and fitness, */         
  9204.  /* are expressly denied.                                            */         
  9205.  /*                                                                  */         
  9206.  /* Provided this copyright notice is included, this software may    */         
  9207.  /* be freely distributed and not offered for sale.                  */         
  9208.  /*                                                                  */         
  9209.  /* Changes or modifications may be made and used only by the maker  */         
  9210.  /* of same, and not further distributed.  Such modifications should */         
  9211.  /* be mailed to the author for consideration for addition to the    */         
  9212.  /* software and incorporation in subsequent releases.               */         
  9213.  /*                                                                  */         
  9214.  /********************************************************************/         
  9215.                                                                                 
  9216. #pragma  csect(code,  "NN@BVPUT")                                               
  9217. #pragma  csect(static,"NN$BVPUT")                                               
  9218. #include "nn.h"                                                                 
  9219. #include "nnbatch.h"                                                            
  9220.                                                                                 
  9221. /****** Report type mismatch error. **********************************/         
  9222.                                                                                 
  9223. static void                                                                     
  9224. type_error(np,var,type1,type2)                                                  
  9225. Rstruc nncb     *np;                                                            
  9226. char            *var;                                                           
  9227. char            *type1;                                                         
  9228. char            *type2;                                                         
  9229. {                                                                               
  9230.                                                                                 
  9231.  ERR4("Type mismatch: \                                                         
  9232. Cannot assign a value of type %s to %s variable %s.",                           
  9233.       type1,type2,var);                                                         
  9234.                                                                                 
  9235.  return;                                                                        
  9236.                                                                                 
  9237. }                                                                               
  9238.                                                                                 
  9239. /****** Set value of symbol table entry. *****************************/         
  9240.                                                                                 
  9241. static void                                                                     
  9242. set_value(np,sp,var,val,type)                                                   
  9243. Rstruc nncb     *np;                                                            
  9244. struct symtab   *sp;                                                            
  9245. char            *var;                                                           
  9246. ANYTYPE          val;                                                           
  9247. enum symtype     type;                                                          
  9248. {                                                                               
  9249.                                                                                 
  9250.  /*------------------------------------------------------------------*          
  9251.   *                                                                  *          
  9252.   * Table of allowable type-to-type settings:                        *          
  9253.   *                                                                  *          
  9254.   * sp->type   |   type      | result                                *          
  9255.   *____________|_____________|_________________________________      *          
  9256.   * STRING     |   STRING    | OK                                    *          
  9257.   *            |   NUMBER    | convert to string via sprintf %d      *          
  9258.   *            |   FLAG      | error                                 *          
  9259.   *____________|_____________|_________________________________      *          
  9260.   * NUMBER     |   STRING    | error                                 *          
  9261.   *            |   NUMBER    | OK                                    *          
  9262.   *            |   FLAG      | convert to 1 or 0                     *          
  9263.   *____________|_____________|_________________________________      *          
  9264.   * FLAG       |   STRING    | error                                 *          
  9265.   *            |   NUMBER    | interpret as nonzero or zero          *          
  9266.   *            |   FLAG      | OK                                    *          
  9267.   *            |             |                                       *          
  9268.   *------------------------------------------------------------------*/         
  9269.                                                                                 
  9270.  switch (sp->type) {                                                            
  9271.    case STRING_SYMTYPE:                                                         
  9272.         switch (type) {                                                         
  9273.           case STRING_SYMTYPE: strcpy(sp->symval,(char *)val);                  
  9274.                                break;                                           
  9275.           case NUMBER_SYMTYPE: sprintf(sp->symval,"%d",(int)val);               
  9276.                                break;                                           
  9277.           case FLAG_SYMTYPE:   type_error(np,var,"FLAG","STRING");              
  9278.                                break;                                           
  9279.         }                                                                       
  9280.         break;                                                                  
  9281.    case NUMBER_SYMTYPE:                                                         
  9282.         switch (type) {                                                         
  9283.           case STRING_SYMTYPE: type_error(np,var,"STRING","NUMBER");            
  9284.                                break;                                           
  9285.           case NUMBER_SYMTYPE: sp->symnum = (int)val;                           
  9286.                                break;                                           
  9287.           case FLAG_SYMTYPE:   sp->symnum = (Fool)val ? 1 : 0;                  
  9288.                                break;                                           
  9289.         }                                                                       
  9290.         break;                                                                  
  9291.    case FLAG_SYMTYPE:                                                           
  9292.         switch (type) {                                                         
  9293.           case STRING_SYMTYPE: type_error(np,var,"STRING","FLAG");              
  9294.                                break;                                           
  9295.           case NUMBER_SYMTYPE: sp->symnum = (int)val ? 1 : 0;                   
  9296.                                break;                                           
  9297.           case FLAG_SYMTYPE:   sp->symnum = (Fool)val ? 1 : 0;                  
  9298.                                break;                                           
  9299.         }                                                                       
  9300.         break;                                                                  
  9301.  }                                                                              
  9302.                                                                                 
  9303.  if (np->debug_file) {                                                          
  9304.    switch (sp->type) {                                                          
  9305.      case STRING_SYMTYPE:  fprintf(np->debug_file,                              
  9306.                                    "NNMbvput: %s set to '%s'\n",                
  9307.                                    sp->symvar, sp->symval);                     
  9308.                            break;                                               
  9309.      case NUMBER_SYMTYPE:  fprintf(np->debug_file,                              
  9310.                                    "NNMbvput: %s set to %d\n",                  
  9311.                                    sp->symvar, sp->symnum);                     
  9312.                            break;                                               
  9313.      case FLAG_SYMTYPE:    fprintf(np->debug_file,                              
  9314.                                    "NNMbvput: %s set to %s\n",                  
  9315.                                    sp->symvar,                                  
  9316.                                    sp->symnum ? "TRUE" : "FALSE");              
  9317.                            break;                                               
  9318.    }                                                                            
  9319.  }                                                                              
  9320.                                                                                 
  9321.  return;                                                                        
  9322. }                                                                               
  9323.                                                                                 
  9324. /****** Put a value into the symbol table. ***************************/         
  9325.                                                                                 
  9326. void                                                                            
  9327. NNMbvput(np,bp,var,type,val)                                                    
  9328. Rstruc nncb         *np;                                                        
  9329. Rstruc batch        *bp;                                                        
  9330. char                *var;                                                       
  9331. enum symtype         type;                                                      
  9332. ANYTYPE              val;                                                       
  9333. {                                                                               
  9334.  Rstruc symtab      *symp;                                                      
  9335.  Rstruc symtab     **sympref;                                                   
  9336.  struct symtab      *sympnew;                                                   
  9337.  struct symtab      *sympleft;                                                  
  9338.  struct symtab      *sympright;                                                 
  9339.  enum symtype        symptype;                                                  
  9340.  int                 varlen;                                                    
  9341.  int                 minimum_value_length;                                      
  9342.  int                 getlen;                                                    
  9343.  int                 comp;                                                      
  9344.  Bool                symbol_found;                                              
  9345.  char                vartest[MAX_SYMBOL_LENGTH];                                
  9346.                                                                                 
  9347.  varlen = strlen(var);                                                          
  9348.  if (varlen < 1 || varlen > MAX_SYMBOL_LENGTH) {                                
  9349.    ERR2(                                                                        
  9350.     "A variable name must be between 1 and %d characters in length.",           
  9351.         MAX_SYMBOL_LENGTH);                                                     
  9352.    return;                                                                      
  9353.  }                                                                              
  9354.                                                                                 
  9355.  memset(vartest,'\0',MAX_SYMBOL_LENGTH);                                        
  9356.  memcpy(vartest,var,varlen);                                                    
  9357.                                                                                 
  9358.  switch (type) {                                                                
  9359.    case STRING_SYMTYPE: minimum_value_length = strlen((char *)val) + 1;         
  9360.                         break;                                                  
  9361.    case NUMBER_SYMTYPE: minimum_value_length = 12;                              
  9362.                         break;                                                  
  9363.    case FLAG_SYMTYPE:   minimum_value_length = 6;                               
  9364.                         break;                                                  
  9365.  }                                                                              
  9366.                                                                                 
  9367.  symbol_found = FALSE;                                                          
  9368.                                                                                 
  9369.  sympleft  = NULL;                                                              
  9370.  sympright = NULL;                                                              
  9371.  sympref   = &bp->symtabp;                                                      
  9372.                                                                                 
  9373.  while ((symp=*sympref)) {                                                      
  9374.    switch ((comp=memcmp(vartest, symp->symvar, MAX_SYMBOL_LENGTH))) {           
  9375.      case 0:   /* equal   */                                                    
  9376.                symbol_found = TRUE;                                             
  9377.                /* free this entry and allocate a new one if this one            
  9378.                   is too small to hold the requested value */                   
  9379.                if (minimum_value_length > symp->vallen) {                       
  9380.                  symptype  = symp->type;                                        
  9381.                  sympleft  = symp->left;                                        
  9382.                  sympright = symp->right;                                       
  9383.                  FREEMAIN(*sympref,"old symbol table entry");                   
  9384.                  *sympref = NULL;                                               
  9385.                  break;                                                         
  9386.                }                                                                
  9387.                else {                                                           
  9388.                  set_value(np,symp,var,val,type);                               
  9389.                  return;                                                        
  9390.                }                                                                
  9391.      case 1:   /* greater */                                                    
  9392.                sympref = &symp->right;                                          
  9393.                continue;                                                        
  9394.      default:  /* less    */                                                    
  9395.                sympref = &symp->left;                                           
  9396.                continue;                                                        
  9397.    }                                                                            
  9398.  }                                                                              
  9399.                                                                                 
  9400.  /* Symbol not found - not allowed, means variable not declared                 
  9401.   */                                                                            
  9402.                                                                                 
  9403.  if (!symbol_found) {                                                           
  9404.    ERR2("The variable %s has not been declared or set to a value.",             
  9405.         var);                                                                   
  9406.    return;                                                                      
  9407.  }                                                                              
  9408.                                                                                 
  9409.  getlen = offsetof(struct symtab, symval) + minimum_value_length;               
  9410.                                                                                 
  9411.  GETMAIN(sympnew, char, getlen, "new symbol table entry");                      
  9412.  if (!sympnew) {                                                                
  9413.    ERR2("Cannot set variable: \                                                 
  9414. Unable to allocate storage to hold value for variable %s.",                     
  9415.         var);                                                                   
  9416.    return;                                                                      
  9417.  }                                                                              
  9418.                                                                                 
  9419.  memcpy(sympnew->symvar, vartest, MAX_SYMBOL_LENGTH);                           
  9420.  sympnew->left   = sympleft;                                                    
  9421.  sympnew->right  = sympright;                                                   
  9422.  sympnew->vallen = minimum_value_length;                                        
  9423.  sympnew->type   = symptype;                                                    
  9424.  *sympref        = sympnew;                                                     
  9425.                                                                                 
  9426.  set_value(np,sympnew,var,val,type);                                            
  9427.                                                                                 
  9428.  return;                                                                        
  9429.                                                                                 
  9430. }                                                                               
  9431.                                                                                 
  9432. ./   ADD NAME=NNMBXFAR,SSI=01230028                                             
  9433.                                                                                 
  9434.  /********************************************************************/         
  9435.  /*                                                                  */         
  9436.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  9437.  /*                                                                  */         
  9438.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  9439.  /* including the implied warranties of merchantability and fitness, */         
  9440.  /* are expressly denied.                                            */         
  9441.  /*                                                                  */         
  9442.  /* Provided this copyright notice is included, this software may    */         
  9443.  /* be freely distributed and not offered for sale.                  */         
  9444.  /*                                                                  */         
  9445.  /* Changes or modifications may be made and used only by the maker  */         
  9446.  /* of same, and not further distributed.  Such modifications should */         
  9447.  /* be mailed to the author for consideration for addition to the    */         
  9448.  /* software and incorporation in subsequent releases.               */         
  9449.  /*                                                                  */         
  9450.  /********************************************************************/         
  9451.                                                                                 
  9452. #pragma  csect(code,  "NN@BXFAR")                                               
  9453. #pragma  csect(static,"NN$BXFAR")                                               
  9454. #include "nn.h"                                                                 
  9455. #include "nnbatch.h"                                                            
  9456.                                                                                 
  9457. /****** Execute batch FOR articles command. **************************/         
  9458.                                                                                 
  9459. struct variablesave {                                                           
  9460.                      int        number;                                         
  9461.                      Bool       read;                                           
  9462.                      Bool       missing;                                        
  9463.                      char      *subject;                                        
  9464.                      char      *date;                                           
  9465.                      char      *from;                                           
  9466.                      char      *messageid;                                      
  9467.                     };                                                          
  9468.                                                                                 
  9469. /****** Set article variables. ***************************************/         
  9470.                                                                                 
  9471. static void                                                                     
  9472. set_article_variables(np,bp,ap,vsp)                                             
  9473. Rstruc nncb                 *np;                                                
  9474. Rstruc batch                *bp;                                                
  9475. Rstruc newsarticle          *ap;                                                
  9476. struct variablesave         *vsp;                                               
  9477. {                                                                               
  9478.  Rstruc newsgroup           *gp = bp->gp;                                       
  9479.  char                        vc;                                                
  9480.                                                                                 
  9481.  vsp->number     = GETA("NUMBER");                                              
  9482.  vsp->read       = GETB("READ");                                                
  9483.  vsp->missing    = GETB("MISSING");                                             
  9484.  vsp->subject    = NNMcopy(np,GETC("SUBJECT"));                                 
  9485.  vsp->date       = NNMcopy(np,GETC("DATE"));                                    
  9486.  vsp->from       = NNMcopy(np,GETC("FROM"));                                    
  9487.  vsp->messageid  = NNMcopy(np,GETC("MESSAGEID"));                               
  9488.                                                                                 
  9489.  vc = V_STATUS(gp,ap->number);                                                  
  9490.                                                                                 
  9491.  SETA("NUMBER",     ap->number);                                                
  9492.  SETB("READ",       vc == V_READ         || vc == V_MISSING_READ);              
  9493.  SETB("MISSING",    vc == V_MISSING_READ || vc == V_MISSING_UNREAD);            
  9494.  SETC("SUBJECT",    ap->subject);                                               
  9495.  SETC("DATE",       ap->date);                                                  
  9496.  SETC("FROM",       ap->from);                                                  
  9497.  SETC("MESSAGEID",  ap->message_id);                                            
  9498.                                                                                 
  9499.  return ;                                                                       
  9500. }                                                                               
  9501.                                                                                 
  9502. /****** Unset articles variables. ************************************/         
  9503.                                                                                 
  9504. static void                                                                     
  9505. unset_article_variables(np,bp,ap,vsp)                                           
  9506. Rstruc nncb                 *np;                                                
  9507. Rstruc batch                *bp;                                                
  9508. Rstruc newsarticle          *ap;                                                
  9509. struct variablesave         *vsp;                                               
  9510. {                                                                               
  9511.                                                                                 
  9512.  SETA("NUMBER",    vsp->number);                                                
  9513.  SETB("READ",      vsp->read);                                                  
  9514.  SETB("MISSING",   vsp->missing);                                               
  9515.  SETC("SUBJECT",   vsp->subject);                                               
  9516.  SETC("DATE",      vsp->date);                                                  
  9517.  SETC("FROM",      vsp->from);                                                  
  9518.  SETC("MESSAGEID", vsp->messageid);                                             
  9519.                                                                                 
  9520.  FREEMAIN(vsp->subject,   "saved copy of SUBJECT");                             
  9521.  FREEMAIN(vsp->date,      "saved copy of DATE");                                
  9522.  FREEMAIN(vsp->from,      "saved copy of FROM");                                
  9523.  FREEMAIN(vsp->messageid, "saved copy of MESSAGEID");                           
  9524.                                                                                 
  9525.  return;                                                                        
  9526. }                                                                               
  9527.                                                                                 
  9528. /****** Reset newsgroup variables. ***********************************/         
  9529.                                                                                 
  9530. static void                                                                     
  9531. reset_newsgroup_variables(np,bp,gp)                                             
  9532. Rstruc nncb                 *np;                                                
  9533. Rstruc batch                *bp;                                                
  9534. Rstruc newsgroup            *gp;                                                
  9535. {                                                                               
  9536.                                                                                 
  9537.  if (gp->real_article_count != NO_VALUE &&                                      
  9538.      gp->real_article_count != gp->fake_article_count) {                        
  9539.    SETA("COUNT"      ,gp->real_article_count);                                  
  9540.  }                                                                              
  9541.  if (gp->real_unread_count != NO_VALUE &&                                       
  9542.      gp->real_unread_count != gp->fake_unread_count) {                          
  9543.    SETA("UNREAD"     ,gp->real_unread_count);                                   
  9544.  }                                                                              
  9545.  if (gp->real_first_article_number != NO_VALUE &&                               
  9546.      gp->real_first_article_number != gp->fake_first_article_number) {          
  9547.    SETA("FIRST"      ,gp->real_first_article_number);                           
  9548.  }                                                                              
  9549.  if (gp->real_last_article_number != NO_VALUE &&                                
  9550.      gp->real_last_article_number != gp->fake_last_article_number) {            
  9551.    SETA("LAST"       ,gp->real_last_article_number);                            
  9552.  }                                                                              
  9553.                                                                                 
  9554.  return ;                                                                       
  9555. }                                                                               
  9556.                                                                                 
  9557. /****** Execute article commands. ************************************/         
  9558.                                                                                 
  9559. static void                                                                     
  9560. execute_article_commands(np,bp,ap,treep)                                        
  9561. Rstruc nncb                 *np;                                                
  9562. Rstruc batch                *bp;                                                
  9563. Rstruc newsarticle          *ap;                                                
  9564. struct cmdtree              *treep;                                             
  9565. {                                                                               
  9566.  struct newsarticle         *saveap;                                            
  9567.                                                                                 
  9568.  for (; treep; treep = treep->next) {                                           
  9569.    bp->runtime_error = FALSE;                                                   
  9570.    saveap = bp->ap;                                                             
  9571.    bp->ap = ap;                                                                 
  9572.    (treep->cmd->proc) (np,bp,treep->cmd);                                       
  9573.    bp->ap = saveap;                                                             
  9574.    SETB("ERROR",bp->runtime_error);                                             
  9575.  }                                                                              
  9576.                                                                                 
  9577.  return;                                                                        
  9578. }                                                                               
  9579.                                                                                 
  9580. /****** Insure article header. *************************************/           
  9581.                                                                                 
  9582. static void                                                                     
  9583. insure_article_header(np,bp,ap)                                                 
  9584. Rstruc nncb                 *np;                                                
  9585. Rstruc batch                *bp;                                                
  9586. Rstruc newsarticle          *ap;                                                
  9587. {                                                                               
  9588.  struct newsgroup           *gp  = bp->gp;                                      
  9589.                                                                                 
  9590.  NNMrarh(np,gp,ap,TRUE,NULL); /* Retrieve article header */                     
  9591.                                                                                 
  9592.  return;                                                                        
  9593. }                                                                               
  9594.                                                                                 
  9595. /****** Test if article passes filter. *****************************/           
  9596.                                                                                 
  9597. static Bool                                                                     
  9598. pass_filter(np,bp,ap,filter)                                                    
  9599. Rstruc nncb                 *np;                                                
  9600. Rstruc batch                *bp;                                                
  9601. Rstruc newsarticle          *ap;                                                
  9602. struct ptree                *filter;                                            
  9603. {                                                                               
  9604.  Bool                        passes_filter;                                     
  9605.                                                                                 
  9606.  if (filter) {                                                                  
  9607.    passes_filter = (Fool)NNMbbexp(np,bp,filter,FLAG_SYMTYPE);                   
  9608.    if (bp->runtime_error) {                                                     
  9609.      bp->request_errors++;                                                      
  9610.      passes_filter = FALSE;                                                     
  9611.    }                                                                            
  9612.  }                                                                              
  9613.  else {                                                                         
  9614.    passes_filter = TRUE;                                                        
  9615.  }                                                                              
  9616.                                                                                 
  9617.  return passes_filter;                                                          
  9618.                                                                                 
  9619. }                                                                               
  9620.                                                                                 
  9621. /****** Test if article passes criterion. ****************************/         
  9622.                                                                                 
  9623. static Bool                                                                     
  9624. pass_criterion(np,bp,ap,which,first,last)                                       
  9625. Rstruc nncb                 *np;                                                
  9626. Rstruc batch                *bp;                                                
  9627. Rstruc newsarticle          *ap;                                                
  9628. enum which_articles          which;                                             
  9629. struct ptree                *first;                                             
  9630. struct ptree                *last;                                              
  9631. {                                                                               
  9632.  Rstruc newsgroup           *gp = bp->gp;                                       
  9633.  int                        firstnum;                                           
  9634.  int                        lastnum;                                            
  9635.                                                                                 
  9636.  if (ap->number ==  NO_VALUE) return FALSE;                                     
  9637.                                                                                 
  9638.  switch (which) {                                                               
  9639.    case ALL_ARTICLES:                                                           
  9640.             return TRUE;                                                        
  9641.    case READ_ARTICLES:                                                          
  9642.             return (V_STATUS(gp,ap->number) == V_READ);                         
  9643.    case UNREAD_ARTICLES:                                                        
  9644.             return (V_STATUS(gp,ap->number) == V_UNREAD);                       
  9645.    case RANGED_ARTICLES:                                                        
  9646.             if (first)                                                          
  9647.                  firstnum = (int)NNMbbexp(np,bp,first,NUMBER_SYMTYPE);          
  9648.             else firstnum = FIRST_ARTICLE_IN_RANGE;                             
  9649.             if (last)                                                           
  9650.                  lastnum = (int)NNMbbexp(np,bp,last, NUMBER_SYMTYPE);           
  9651.             else lastnum  = firstnum;                                           
  9652.             return (ap->number >= firstnum && ap->number <= lastnum);           
  9653.    case NO_ARTICLES:                                                            
  9654.             return FALSE;                                                       
  9655.    default:                                                                     
  9656.             return FALSE;                                                       
  9657.  }                                                                              
  9658.                                                                                 
  9659. }                                                                               
  9660.                                                                                 
  9661. /****** Execute batch FOR articles command. **************************/         
  9662.                                                                                 
  9663. void                                                                            
  9664. NNMbxfar(np,bp,cmdp)                                                            
  9665. Rstruc nncb                 *np;                                                
  9666. Rstruc batch                *bp;                                                
  9667. Rstruc newscmd              *cmdp;                                              
  9668. {                                                                               
  9669.  Rstruc newsgroup           *gp;                                                
  9670.  Rstruc newsarticle         *ap;                                                
  9671.  struct newsgroup           *gp1;                                               
  9672.  struct ptree               *filter;                                            
  9673.  struct cmdtree             *treep;                                             
  9674.  struct ptree               *first;                                             
  9675.  struct ptree               *last;                                              
  9676.  enum which_articles         which;                                             
  9677.  struct variablesave         varsave;                                           
  9678.                                                                                 
  9679.  filter = cmdp->cmd.ncmd.fors.filter;                                           
  9680.  treep  = cmdp->cmd.ncmd.fors.treep;                                            
  9681.  which  = cmdp->cmd.ncmd.fors.crit.which;                                       
  9682.  first  = cmdp->cmd.ncmd.fors.crit.first;                                       
  9683.  last   = cmdp->cmd.ncmd.fors.crit.last;                                        
  9684.                                                                                 
  9685.  gp = bp->gp;                                                                   
  9686.                                                                                 
  9687.  /* Logic:  (1) apply "which" criteria                                          
  9688.   *         (2) set variables for articles remaining                            
  9689.   *         (3) apply filters                                                   
  9690.   * Rationale:  Variables must be set before filters can use them.              
  9691.   *             But criteria can be used to reduce the load.                    
  9692.   */                                                                            
  9693.                                                                                 
  9694.  /* code copied from NNMpng */                                                  
  9695.                                                                                 
  9696.  np->current_newsgroup   = gp;                                                  
  9697.  np->newsgroup_selected  = FALSE;                                               
  9698.                                                                                 
  9699.  np->newsgroup_not_found = FALSE;                                               
  9700.                                                                                 
  9701.  if (gp->first_article == NULL) gp1 = do_newsgroup_by_address(np,gp);           
  9702.  else                           gp1 = gp;                                       
  9703.                                                                                 
  9704.  if (np->newsgroup_not_found) {                                                 
  9705.    SetNoSuchGroup(gp);                                                          
  9706.    gp->real_article_count = 0;                                                  
  9707.    gp->real_unread_count  = 0;                                                  
  9708.  }                                                                              
  9709.  else if (gp1) {                                                                
  9710.    bp->gp = gp1;                                                                
  9711.    gp = gp1;                                                                    
  9712.    if (NNMraarh(np,gp)) {            /* Retrieve all article headers */         
  9713.      reset_newsgroup_variables(np,bp,gp);                                       
  9714.      if (gp->first_article) {                                                   
  9715.                                                                                 
  9716.        /* first loop is to make sure the articles are all there */              
  9717.                                                                                 
  9718.        ap = gp->first_article;                                                  
  9719.        while (ap <= gp->real_last_article) {                                    
  9720.          if (pass_criterion(np,bp,ap,which,first,last)) {                       
  9721.            insure_article_header(np,bp,ap);                                     
  9722.            if (np->article_error_found) {                                       
  9723.              ap = gp->first_article;                                            
  9724.              continue;                                                          
  9725.            }                                                                    
  9726.          }                                                                      
  9727.          ap++;                                                                  
  9728.        }                                                                        
  9729.                                                                                 
  9730.        /* second loop is to actually process the articles */                    
  9731.                                                                                 
  9732.        for (ap = gp->first_article; ap <= gp->fake_last_article; ap++) {        
  9733.          if (pass_criterion(np,bp,ap,which,first,last)) {                       
  9734.            set_article_variables(np,bp,ap,&varsave);                            
  9735.            if (pass_filter(np,bp,ap,filter)) {                                  
  9736.              execute_article_commands(np,bp,ap,treep);                          
  9737.            }                                                                    
  9738.            unset_article_variables(np,bp,ap,&varsave);                          
  9739.          }                                                                      
  9740.        }                                                                        
  9741.      }                                                                          
  9742.    }                                                                            
  9743.  }                                                                              
  9744.                                                                                 
  9745.  np->current_newsgroup  = NULL;                                                 
  9746.  np->newsgroup_selected = FALSE;                                                
  9747.                                                                                 
  9748.  return;                                                                        
  9749. }                                                                               
  9750.                                                                                 
  9751. ./   ADD NAME=NNMBXFNG,SSI=01060057                                             
  9752.                                                                                 
  9753.  /********************************************************************/         
  9754.  /*                                                                  */         
  9755.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  9756.  /*                                                                  */         
  9757.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  9758.  /* including the implied warranties of merchantability and fitness, */         
  9759.  /* are expressly denied.                                            */         
  9760.  /*                                                                  */         
  9761.  /* Provided this copyright notice is included, this software may    */         
  9762.  /* be freely distributed and not offered for sale.                  */         
  9763.  /*                                                                  */         
  9764.  /* Changes or modifications may be made and used only by the maker  */         
  9765.  /* of same, and not further distributed.  Such modifications should */         
  9766.  /* be mailed to the author for consideration for addition to the    */         
  9767.  /* software and incorporation in subsequent releases.               */         
  9768.  /*                                                                  */         
  9769.  /********************************************************************/         
  9770.                                                                                 
  9771. #pragma  csect(code,  "NN@BXFNG")                                               
  9772. #pragma  csect(static,"NN$BXFNG")                                               
  9773. #include "nn.h"                                                                 
  9774. #include "nnbatch.h"                                                            
  9775.                                                                                 
  9776. struct variablesave {                                                           
  9777.                      char      *group;                                          
  9778.                      Bool       registered;                                     
  9779.                      Bool       newgroup;                                       
  9780.                      Bool       nosuchgroup;                                    
  9781.                      int        count;                                          
  9782.                      int        unread;                                         
  9783.                      int        first;                                          
  9784.                      int        last;                                           
  9785.                     };                                                          
  9786.                                                                                 
  9787. /****** Set newsgroup variables. *************************************/         
  9788.                                                                                 
  9789. static void                                                                     
  9790. set_newsgroup_variables(np,bp,gp,vsp)                                           
  9791. Rstruc nncb                 *np;                                                
  9792. Rstruc batch                *bp;                                                
  9793. Rstruc newsgroup            *gp;                                                
  9794. struct variablesave         *vsp;                                               
  9795. {                                                                               
  9796.                                                                                 
  9797.  vsp->group       = NNMcopy(np,GETC("GROUP"));                                  
  9798.  vsp->registered  = GETB("REGISTERED");                                         
  9799.  vsp->newgroup    = GETB("NEWGROUP");                                           
  9800.  vsp->nosuchgroup = GETB("NOSUCHGROUP");                                        
  9801.  vsp->count       = GETA("COUNT");                                              
  9802.  vsp->unread      = GETA("UNREAD");                                             
  9803.  vsp->first       = GETA("FIRST");                                              
  9804.  vsp->last        = GETA("LAST");                                               
  9805.                                                                                 
  9806.  SETC("GROUP"      ,gp->name);                                                  
  9807.  SETA("COUNT"      ,gp->fake_article_count);                                    
  9808.  SETA("UNREAD"     ,gp->fake_unread_count);                                     
  9809.  SETA("FIRST"      ,gp->fake_first_article_number);                             
  9810.  SETA("LAST"       ,gp->fake_last_article_number);                              
  9811.  SETB("REGISTERED" ,(gp->registered > 0) ? TRUE : FALSE);                       
  9812.                                                                                 
  9813.  if (NewGroup(gp)) {  /* if new newsgroup */                                    
  9814.    fprintf(np->batch_outfile,"New newsgroup: %s (%d articles)\n",               
  9815.                gp->name, gp->fake_article_count);                               
  9816.    gp->registered = -1;                                                         
  9817.    SETB("NEWGROUP",TRUE);                                                       
  9818.  }                                                                              
  9819.  else if (gp->registered == -1) {  /* old way: if new newsgroup */              
  9820.    fprintf(np->batch_outfile,"New newsgroup: %s (%d articles)\n",               
  9821.                gp->name, gp->fake_article_count);                               
  9822.    SetNewGroup(gp);                                                             
  9823.    SETB("NEWGROUP",TRUE);                                                       
  9824.  }                                                                              
  9825.  else {                                                                         
  9826.    OffNewGroup(gp);                                                             
  9827.    SETB("NEWGROUP",FALSE);                                                      
  9828.  }                                                                              
  9829.                                                                                 
  9830.  if (BogusGroup(gp)) {                                                          
  9831.    fprintf(np->batch_outfile,"Nonexistent newsgroup: %s\n",                     
  9832.                              gp->name);                                         
  9833.    SetNoSuchGroup(gp);                                                          
  9834.    SETB("NOSUCHGROUP",TRUE);                                                    
  9835.  }                                                                              
  9836.  else {                                                                         
  9837.    SETB("NOSUCHGROUP",FALSE);                                                   
  9838.  }                                                                              
  9839.                                                                                 
  9840.  return ;                                                                       
  9841. }                                                                               
  9842.                                                                                 
  9843. /****** Unset newsgroup variables. **********************************/          
  9844.                                                                                 
  9845. static void                                                                     
  9846. unset_newsgroup_variables(np,bp,gp,vsp)                                         
  9847. Rstruc nncb                 *np;                                                
  9848. Rstruc batch                *bp;                                                
  9849. Rstruc newsgroup            *gp;                                                
  9850. struct variablesave         *vsp;                                               
  9851. {                                                                               
  9852.                                                                                 
  9853.  SETC("GROUP"       ,vsp->group);                                               
  9854.  SETB("REGISTERED"  ,vsp->registered);                                          
  9855.  SETB("NEWGROUP"    ,vsp->newgroup);                                            
  9856.  SETB("NOSUCHGROUP" ,vsp->nosuchgroup);                                         
  9857.  SETA("COUNT"       ,vsp->count);                                               
  9858.  SETA("UNREAD"      ,vsp->unread);                                              
  9859.  SETA("FIRST"       ,vsp->first);                                               
  9860.  SETA("LAST"        ,vsp->last);                                                
  9861.                                                                                 
  9862.  FREEMAIN(vsp->group,"saved copy of GROUP");                                    
  9863.                                                                                 
  9864.  return ;                                                                       
  9865. }                                                                               
  9866.                                                                                 
  9867. /****** See if new newsgroup. ****************************************/         
  9868.                                                                                 
  9869. static void                                                                     
  9870. see_if_new_newsgroup(np,bp,gp)                                                  
  9871. Rstruc nncb                 *np;                                                
  9872. Rstruc batch                *bp;                                                
  9873. Rstruc newsgroup            *gp;                                                
  9874. {                                                                               
  9875.                                                                                 
  9876.  if (NewGroup(gp)) {  /* if new newsgroup */                                    
  9877.                                                                                 
  9878.    if (GETB("AUTOREGISTER")) {                                                  
  9879.      gp->registered = 1;                                                        
  9880.      SETB("REGISTERED",TRUE);                                                   
  9881.      fprintf(np->batch_outfile,                                                 
  9882.             "Added newsgroup %s as REGISTERED\n", gp->name);                    
  9883.    }                                                                            
  9884.    else {                                                                       
  9885.      gp->registered = 0;                                                        
  9886.      SETB("REGISTERED",FALSE);                                                  
  9887.      fprintf(np->batch_outfile,                                                 
  9888.             "Added newsgroup %s as UNREGISTERED\n", gp->name);                  
  9889.    }                                                                            
  9890.  }                                                                              
  9891.                                                                                 
  9892.  return;                                                                        
  9893. }                                                                               
  9894.                                                                                 
  9895. /****** See if bogus newsgroup. **************************************/         
  9896.                                                                                 
  9897. static void                                                                     
  9898. see_if_bogus_newsgroup(np,bp,gp)                                                
  9899. Rstruc nncb                 *np;                                                
  9900. Rstruc batch                *bp;                                                
  9901. Rstruc newsgroup            *gp;                                                
  9902. {                                                                               
  9903.                                                                                 
  9904.  if (BogusGroup(gp)) {                                                          
  9905.                                                                                 
  9906.    if (GETB("AUTODELETE")) {                                                    
  9907.      SetNoSuchGroup(gp);                                                        
  9908.      OffGroupListed(gp);                                                        
  9909.      fprintf(np->batch_outfile,                                                 
  9910.             "Deleted newsgroup %s\n", gp->name);                                
  9911.    }                                                                            
  9912.    else {                                                                       
  9913.      SetGroupListed(gp);                                                        
  9914.      fprintf(np->batch_outfile,                                                 
  9915.             "Kept newsgroup %s\n", gp->name);                                   
  9916.    }                                                                            
  9917.  }                                                                              
  9918.                                                                                 
  9919.  return;                                                                        
  9920. }                                                                               
  9921.                                                                                 
  9922. /****** Execute newsgroup commands. **********************************/         
  9923.                                                                                 
  9924. static void                                                                     
  9925. execute_newsgroup_commands(np,bp,gp,treep)                                      
  9926. Rstruc nncb                 *np;                                                
  9927. Rstruc batch                *bp;                                                
  9928. Rstruc newsgroup            *gp;                                                
  9929. struct cmdtree              *treep;                                             
  9930. {                                                                               
  9931.  struct newsgroup           *savegp;                                            
  9932.                                                                                 
  9933.  for (; treep; treep = treep->next) {                                           
  9934.    bp->runtime_error = FALSE;                                                   
  9935.    savegp = bp->gp;                                                             
  9936.    bp->gp = gp;                                                                 
  9937.    (treep->cmd->proc) (np,bp,treep->cmd);                                       
  9938.    bp->gp = savegp;                                                             
  9939.    SETB("ERROR",bp->runtime_error);                                             
  9940.  }                                                                              
  9941.                                                                                 
  9942.  return;                                                                        
  9943. }                                                                               
  9944.                                                                                 
  9945. /****** Test if newsgroup passes filter. *****************************/         
  9946.                                                                                 
  9947. static Bool                                                                     
  9948. pass_filter(np,bp,gp,filter)                                                    
  9949. Rstruc nncb                 *np;                                                
  9950. Rstruc batch                *bp;                                                
  9951. Rstruc newsgroup            *gp;                                                
  9952. struct ptree                *filter;                                            
  9953. {                                                                               
  9954.  Bool                        passes_filter;                                     
  9955.                                                                                 
  9956.  if (filter) {                                                                  
  9957.    passes_filter = (Fool)NNMbbexp(np,bp,filter,FLAG_SYMTYPE);                   
  9958.    if (bp->runtime_error) {                                                     
  9959.      bp->request_errors++;                                                      
  9960.      passes_filter = FALSE;                                                     
  9961.    }                                                                            
  9962.  }                                                                              
  9963.  else {                                                                         
  9964.    passes_filter = TRUE;                                                        
  9965.  }                                                                              
  9966.                                                                                 
  9967.  return passes_filter;                                                          
  9968.                                                                                 
  9969. }                                                                               
  9970.                                                                                 
  9971. /****** Match group name against group string. ***********************/         
  9972.                                                                                 
  9973. static Bool                                                                     
  9974. match(np,bp,name,string)                                                        
  9975. Rstruc nncb                 *np;                                                
  9976. Rstruc batch                *bp;                                                
  9977. char    *name;                                                                  
  9978. char    *string;                                                                
  9979. {                                                                               
  9980.                                                                                 
  9981.  return FALSE;                                                                  
  9982. }                                                                               
  9983.                                                                                 
  9984. /****** Test if newsgroup passes criterion. **************************/         
  9985.                                                                                 
  9986. static Bool                                                                     
  9987. pass_criterion(np,bp,gp,which,groups)                                           
  9988. Rstruc nncb                 *np;                                                
  9989. Rstruc batch                *bp;                                                
  9990. Rstruc newsgroup            *gp;                                                
  9991. enum which_newsgroups        which;                                             
  9992. struct ptree                *groups;                                            
  9993. {                                                                               
  9994.  char                       *groupstring;                                       
  9995.                                                                                 
  9996.  if (groups) groupstring = NNMbbexp(np,bp,groups,STRING_SYMTYPE);               
  9997.                                                                                 
  9998.  switch (which) {                                                               
  9999.    case ALL_NEWSGROUPS:           return TRUE;                                  
  10000.    case REGISTERED_NEWSGROUPS:    return (gp->registered >  0);                 
  10001.    case UNREGISTERED_NEWSGROUPS:  return (gp->registered == 0);                 
  10002.    case NAMED_NEWSGROUPS:                                                       
  10003.  fprintf(np->batch_outfile,"Sorry, cannot handle NAMED_NEWSGROUPS.\n");         
  10004.                                   return match(gp->name,groupstring);           
  10005.    case MASKED_NEWSGROUPS:                                                      
  10006.  fprintf(np->batch_outfile,"Sorry, cannot handle MASKED_NEWSGROUPS.\n");        
  10007.                                   return match(gp->name,groupstring);           
  10008.    case NO_NEWSGROUPS:            return FALSE;                                 
  10009.    default:                       return FALSE;                                 
  10010.  }                                                                              
  10011.                                                                                 
  10012. }                                                                               
  10013.                                                                                 
  10014. /****** Execute batch FOR newsgroups command. ************************/         
  10015.                                                                                 
  10016. void                                                                            
  10017. NNMbxfng(np,bp,cmdp)                                                            
  10018. Rstruc nncb                 *np;                                                
  10019. Rstruc batch                *bp;                                                
  10020. Rstruc newscmd              *cmdp;                                              
  10021. {                                                                               
  10022.  Rstruc newsgroup           *gp;                                                
  10023.  struct ptree               *filter;                                            
  10024.  struct cmdtree             *treep;                                             
  10025.  struct ptree               *groups;                                            
  10026.  enum which_newsgroups       which;                                             
  10027.  struct variablesave         varsave;                                           
  10028.  Bool                        serverlist;                                        
  10029.                                                                                 
  10030.  filter = cmdp->cmd.icmd.fors.filter;                                           
  10031.  treep  = cmdp->cmd.icmd.fors.treep;                                            
  10032.  which  = cmdp->cmd.icmd.fors.crit.which;                                       
  10033.  groups = cmdp->cmd.icmd.fors.crit.groups;                                      
  10034.                                                                                 
  10035.  /* Connect to server. */                                                       
  10036.                                                                                 
  10037.  if (!NNMbconn(np,bp)) {                                                        
  10038.    fprintf(np->batch_outfile,"No newsgroup commands executed.\n");              
  10039.    bp->request_errors++;                                                        
  10040.    return;                                                                      
  10041.  }                                                                              
  10042.                                                                                 
  10043.  /* Determine source of newsgroups - SERVER or NEWSRC. */                       
  10044.  /* If SERVERLIST is true, do an NNTP list.  Otherwise */                       
  10045.  /* use NEWSRC and do individual group requests...     */                       
  10046.                                                                                 
  10047.  /* If we do get the newsgroups via LIST, do it only once. */                   
  10048.                                                                                 
  10049.  serverlist = GETB("SERVERLIST");                                               
  10050.                                                                                 
  10051.  if (serverlist) {                                                              
  10052.    if (!bp->newsgroups_retrieved) {                                             
  10053.      (void)NNMdlang(np,LIST_ALL); /* get list of all grps fr server */          
  10054.      bp->newsgroups_retrieved = TRUE;                                           
  10055.    }                                                                            
  10056.  }                                                                              
  10057.                                                                                 
  10058.  /* Logic:  (1) apply "which" criteria                                          
  10059.   *         (2) set variables for groups remaining                              
  10060.   *         (3) apply filters                                                   
  10061.   * Rationale:  Variables must be set before filters can use them.              
  10062.   *             But criteria can be used to reduce the load.                    
  10063.   */                                                                            
  10064.                                                                                 
  10065.  /* The list of newsgroups has already been built from newsrc at this           
  10066.   * point.  Now, if the source is the server, then ask NNTP to get              
  10067.   * the current list of newsgroups and process it against the list              
  10068.   * from NEWSRC.  If the source is NEWSRC, then get the current status          
  10069.   * of each newsgroup via the NNTP "group" command (slow).                      
  10070.   */                                                                            
  10071.                                                                                 
  10072.  /* Note that the position of see_if_new_newsgroup determines if new            
  10073.   * newsgroups are to be registered depending on AUTOREGISTER *after*           
  10074.   * the filtering or *before*.  If *after*, then all groups that are            
  10075.   * not handled get autoregistered as DEREGISTERED.                             
  10076.   */                                                                            
  10077.                                                                                 
  10078.  for (gp = np->first_newsgroup; gp; gp = gp->next) {                            
  10079.    if (pass_criterion(np,bp,gp,which,groups)) {                                 
  10080.      if (!serverlist) {                                                         
  10081.        do_newsgroup_by_address(np,gp);                                          
  10082.        if (np->newsgroup_not_found) {                                           
  10083.          SetNoSuchGroup(gp);                                                    
  10084.          gp->real_article_count = 0;                                            
  10085.          gp->real_unread_count  = 0;                                            
  10086.        }                                                                        
  10087.      }                                                                          
  10088.      set_newsgroup_variables(np,bp,gp,&varsave);                                
  10089.      if (pass_filter(np,bp,gp,filter)) {                                        
  10090.        see_if_new_newsgroup(np,bp,gp);                                          
  10091.        see_if_bogus_newsgroup(np,bp,gp);                                        
  10092.        if (!NoSuchGroup(gp)) {                                                  
  10093.          execute_newsgroup_commands(np,bp,gp,treep);                            
  10094.        }                                                                        
  10095.      }                                                                          
  10096.      unset_newsgroup_variables(np,bp,gp,&varsave);                              
  10097.    }                                                                            
  10098.  }                                                                              
  10099.                                                                                 
  10100.  return;                                                                        
  10101. }                                                                               
  10102.                                                                                 
  10103. ./   ADD NAME=NNMCLRNG,SSI=010A0037                                             
  10104.                                                                                 
  10105.  /********************************************************************/         
  10106.  /*                                                                  */         
  10107.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  10108.  /*                                                                  */         
  10109.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  10110.  /* including the implied warranties of merchantability and fitness, */         
  10111.  /* are expressly denied.                                            */         
  10112.  /*                                                                  */         
  10113.  /* Provided this copyright notice is included, this software may    */         
  10114.  /* be freely distributed and not offered for sale.                  */         
  10115.  /*                                                                  */         
  10116.  /* Changes or modifications may be made and used only by the maker  */         
  10117.  /* of same, and not further distributed.  Such modifications should */         
  10118.  /* be mailed to the author for consideration for addition to the    */         
  10119.  /* software and incorporation in subsequent releases.               */         
  10120.  /*                                                                  */         
  10121.  /********************************************************************/         
  10122.                                                                                 
  10123. #pragma  csect(code,  "NN@CLRNG")                                               
  10124. #pragma  csect(static,"NN$CLRNG")                                               
  10125. #include "nn.h"                                                                 
  10126.                                                                                 
  10127. /****** Clear newsgroups. ********************************************/         
  10128.                                                                                 
  10129. void                                                                            
  10130. NNMclrng(np)                                                                    
  10131. Rstruc nncb           *np;                                                      
  10132. {                                                                               
  10133.  Rstruc newsgroup     *gp1;                                                     
  10134.  Rstruc newsgroup     *gp2;                                                     
  10135.  Rstruc newsarticle   *ap;                                                      
  10136.                                                                                 
  10137.  np->newsgroup_selected = FALSE;                                                
  10138.  np->new_newsgroup_count = 0;                                                   
  10139.                                                                                 
  10140.  gp1=np->first_newsgroup;                                                       
  10141.  while (gp1) {                                                                  
  10142.   gp2 = gp1->next;                                                              
  10143.                                                                                 
  10144.   if (gp1->first_article) {                                                     
  10145.     for (ap = gp1->first_article; ap <= gp1->real_last_article; ap++) {         
  10146.       NNMclrtx(np,ap);                                                          
  10147.     }                                                                           
  10148.     FREEMAIN(gp1->first_article,    "newsgroup articles");                      
  10149.   }                                                                             
  10150.                                                                                 
  10151.   FREEMAIN(gp1->article_vector,     "newsgroup article vector");                
  10152.   if (gp1->saved_newsrc_line != gp1->saved_newsrc_data) {                       
  10153.     FREEMAIN(gp1->saved_newsrc_line,"newsgroup newsrc line");                   
  10154.   }                                                                             
  10155.   FREEMAIN(gp1,                     "newsgroup");                               
  10156.   gp1 = gp2;                                                                    
  10157.  }                                                                              
  10158.                                                                                 
  10159.  np->first_newsgroup      = NULL;                                               
  10160.  np->first_newsgroup_alt  = NULL;                                               
  10161.  np->current_newsgroup    = NULL;                                               
  10162.  np->last_newsgroup       = NULL;                                               
  10163.  np->last_added_newsgroup = NULL;                                               
  10164.                                                                                 
  10165.  return;                                                                        
  10166. }                                                                               
  10167.                                                                                 
  10168. ./   ADD NAME=NNMCLRTX,SSI=01030000                                             
  10169.                                                                                 
  10170.  /********************************************************************/         
  10171.  /*                                                                  */         
  10172.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  10173.  /*                                                                  */         
  10174.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  10175.  /* including the implied warranties of merchantability and fitness, */         
  10176.  /* are expressly denied.                                            */         
  10177.  /*                                                                  */         
  10178.  /* Provided this copyright notice is included, this software may    */         
  10179.  /* be freely distributed and not offered for sale.                  */         
  10180.  /*                                                                  */         
  10181.  /* Changes or modifications may be made and used only by the maker  */         
  10182.  /* of same, and not further distributed.  Such modifications should */         
  10183.  /* be mailed to the author for consideration for addition to the    */         
  10184.  /* software and incorporation in subsequent releases.               */         
  10185.  /*                                                                  */         
  10186.  /********************************************************************/         
  10187.                                                                                 
  10188. #pragma  csect(code,  "NN@CLRTX")                                               
  10189. #pragma  csect(static,"NN$CLRTX")                                               
  10190. #include "nn.h"                                                                 
  10191.                                                                                 
  10192. /****** Clear text. **************************************************/         
  10193.                                                                                 
  10194. void                                                                            
  10195. NNMclrtx(np,ap)                                                                 
  10196. Rstruc nncb           *np;                                                      
  10197. Rstruc newsarticle    *ap;                                                      
  10198.                                                                                 
  10199. {                                                                               
  10200.  Rstruc texthdr       *thp;                                                     
  10201.  Rstruc textline      *tp1;                                                     
  10202.  Rstruc textline      *tp2;                                                     
  10203.                                                                                 
  10204.  /* If article is not specified, use main nncb, else article's text */          
  10205.                                                                                 
  10206.  thp = (ap ? &ap->thdr : &np->thdr);                                            
  10207.                                                                                 
  10208.  tp1=thp->first_text_line;                                                      
  10209.  while (tp1) {                                                                  
  10210.   tp2 = tp1->next;                                                              
  10211.   FREEMAIN(tp1,"text line");                                                    
  10212.   tp1 = tp2;                                                                    
  10213.  }                                                                              
  10214.                                                                                 
  10215.  thp->text_body_line    = NULL;                                                 
  10216.  thp->first_text_line   = NULL;                                                 
  10217.  thp->current_text_line = NULL;                                                 
  10218.  thp->last_text_line    = NULL;                                                 
  10219.  thp->text_line_count   = 0;                                                    
  10220.  thp->text_max_length   = 0;                                                    
  10221.  thp->text_max_tab_expanded_length   = 0;                                       
  10222.                                                                                 
  10223.  return;                                                                        
  10224.                                                                                 
  10225. }                                                                               
  10226.                                                                                 
  10227. ./   ADD NAME=NNMCNRF,SSI=01200039                                              
  10228.                                                                                 
  10229.  /********************************************************************/         
  10230.  /*                                                                  */         
  10231.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  10232.  /*                                                                  */         
  10233.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  10234.  /*                                                                  */         
  10235.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  10236.  /* including the implied warranties of merchantability and fitness, */         
  10237.  /* are expressly denied.                                            */         
  10238.  /*                                                                  */         
  10239.  /* Provided this copyright notice is included, this software may    */         
  10240.  /* be freely distributed and not offered for sale.                  */         
  10241.  /*                                                                  */         
  10242.  /* Changes or modifications may be made and used only by the maker  */         
  10243.  /* of same, and not further distributed.  Such modifications should */         
  10244.  /* be mailed to the author for consideration for addition to the    */         
  10245.  /* software and incorporation in subsequent releases.               */         
  10246.  /*                                                                  */         
  10247.  /********************************************************************/         
  10248.                                                                                 
  10249. #pragma  csect(code,  "NN@CNRF ")                                               
  10250. #pragma  csect(static,"NN$CNRF ")                                               
  10251. #include "nn.h"                                                                 
  10252.                                                                                 
  10253. /*** Write to newsrc file. *******************************************/         
  10254.                                                                                 
  10255. static Bool                                                                     
  10256. write_to_newsrc(np,newsrc_line,thing)                                           
  10257. Rstruc nncb        *np;                                                         
  10258. char               *newsrc_line;                                                
  10259. char               *thing;                                                      
  10260. {                                                                               
  10261.  char              *newlinep;                                                   
  10262.  Bool               write_ok = TRUE;                                            
  10263.                                                                                 
  10264.  newlinep = strchr(thing,'\n');                                                 
  10265.  if (newlinep) {                                                                
  10266.    while (newlinep) {                                                           
  10267.      strncat(newsrc_line,thing,newlinep-thing);                                 
  10268.      if (fprintf(np->newsrc_file,"%s\n",newsrc_line) < 0)                       
  10269.          write_ok = FALSE;                                                      
  10270.      strcpy(newsrc_line,"");                                                    
  10271.      thing = newlinep + 1;                                                      
  10272.      newlinep = strchr(thing,'\n');                                             
  10273.    }                                                                            
  10274.    strcat(newsrc_line,thing);                                                   
  10275.    return write_ok;                                                             
  10276.  }                                                                              
  10277.                                                                                 
  10278.  if (strlen(newsrc_line) + strlen(thing) > 250) {                               
  10279.    if (fprintf(np->newsrc_file,"%s\n",newsrc_line) < 0)                         
  10280.        write_ok = FALSE;                                                        
  10281.    strcpy(newsrc_line," ");                                                     
  10282.  }                                                                              
  10283.  strcat(newsrc_line,thing);                                                     
  10284.  return write_ok;                                                               
  10285. }                                                                               
  10286.                                                                                 
  10287. /****** Close NEWSRC file. *******************************************/         
  10288.                                                                                 
  10289. void                                                                            
  10290. NNMcnrf(np,what_to_open,updating)                                               
  10291. Rstruc nncb         *np;                                                        
  10292. char                *what_to_open;                                              
  10293. Fool                 updating;                                                  
  10294. {                                                                               
  10295.  Rstruc newsgroup   *gp1;                                                       
  10296.  int                 newsrc_unread;                                             
  10297.  int                 newsrc_topnum;                                             
  10298.  int                 newsrc_count;                                              
  10299.  register int        iv;                                                        
  10300.  int                 read0;                                                     
  10301.  int                 read1;                                                     
  10302.  int                 read2;                                                     
  10303.  Bool                write_ok;                                                  
  10304.  char                newsrc_line[257];                                          
  10305.  char                newsrc_numb[32];                                           
  10306.                                                                                 
  10307.  write_ok = TRUE;                                                               
  10308.                                                                                 
  10309.  /* If the file is currently open for input, close it first. */                 
  10310.                                                                                 
  10311.  if (np->newsrc_file) {                                                         
  10312.    if (fclose(np->newsrc_file) < 0) {                                           
  10313.      fprintf(stderr,"%s: Error closing NEWSRC file\n",what_to_open);            
  10314.    }                                                                            
  10315.    np->newsrc_file = NULL;                                                      
  10316.  }                                                                              
  10317.                                                                                 
  10318.  if (!updating) return;                                                         
  10319.                                                                                 
  10320.  /* Open the file for output.  This will empty it at first. */                  
  10321.                                                                                 
  10322.  if (!what_to_open) what_to_open = np->newsrc_to_open;                          
  10323.                                                                                 
  10324.  np->newsrc_file = fopen(what_to_open,"w");                                     
  10325.  if (np->newsrc_file == NULL) {                                                 
  10326.    perror("Cannot open NEWSRC file");                                           
  10327.    return;                                                                      
  10328.  }                                                                              
  10329.                                                                                 
  10330.  if (np->update_rewriting_newsrc) {                                             
  10331.    if (!np->batch_mode) {                                                       
  10332.      (void)NNMispf(np,"CONTROL DISPLAY LOCK");                                  
  10333.      (void)NNMispf(np,"DISPLAY PANEL(NNMLUNRC)");                               
  10334.    }                                                                            
  10335.  }                                                                              
  10336.                                                                                 
  10337.  /* Write current status into the file. */                                      
  10338.                                                                                 
  10339.  /********************************************************************/         
  10340.  /*                                                                  */         
  10341.  /* Note:  The format used here is designed to be compatible with    */         
  10342.  /*        the format used by ANU-NEWS.  This is not an attempt to   */         
  10343.  /*        duplicate the "look and feel" of ANU-NEWS - it is just    */         
  10344.  /*        to be compatible with the saved state of VAX NEWS users.  */         
  10345.  /*                                                                  */         
  10346.  /********************************************************************/         
  10347.                                                                                 
  10348.  /* First record: time of last update in hex, current newsgroup, blah */        
  10349.                                                                                 
  10350.  if (fprintf(np->newsrc_file,"%.6s %.6s %s\n",                                  
  10351.             np->lastNGdate, np->lastNGtime,                                     
  10352.             np->current_newsgroup ? np->current_newsgroup->name : " ")          
  10353.      < 0) write_ok = FALSE;                                                     
  10354.                                                                                 
  10355.  /* Then: for each newsgroup, the following data...                             
  10356.   *                                                                             
  10357.   * newsgroupname: (registration_priority) [unread,topnum] read-items           
  10358.   *                                                                             
  10359.   */                                                                            
  10360.                                                                                 
  10361.  for (gp1=np->first_newsgroup; gp1; gp1=gp1->next) {                            
  10362.                                                                                 
  10363.    /* special case of NNTP LIST high number being greater than                  
  10364.     * NNTP GROUP high number, meaning latest article(s) missing                 
  10365.     */                                                                          
  10366.                                                                                 
  10367.    if (GroupListed(gp1) &&                                                      
  10368.      gp1->fake_last_article_number > gp1->real_last_article_number) {           
  10369.     newsrc_topnum = gp1->fake_last_article_number;                              
  10370.    }                                                                            
  10371.    else {                                                                       
  10372.     newsrc_topnum = (gp1->real_last_article_number == NO_VALUE                  
  10373.                      ? gp1->fake_last_article_number                            
  10374.                      : gp1->real_last_article_number);                          
  10375.    }                                                                            
  10376.    newsrc_unread = (gp1->real_unread_count == NO_VALUE                          
  10377.                     ? gp1->fake_unread_count                                    
  10378.                     : gp1->real_unread_count);                                  
  10379.    newsrc_count  = (gp1->real_article_count == NO_VALUE                         
  10380.                     ? gp1->fake_article_count                                   
  10381.                     : gp1->real_article_count);                                 
  10382.                                                                                 
  10383.    if (!NoSuchGroup(gp1)) { /* Skip groups that don't really exist */           
  10384.                                                                                 
  10385.      /* The following is a hack for "new newsgroups" */                         
  10386.      if (gp1->registered < 0) gp1->registered = 0;                              
  10387.                                                                                 
  10388.      sprintf(newsrc_line,"%s: (%d) [%d,%d]",                                    
  10389.           /* groupname */    gp1->name,                                         
  10390.           /* reg/prio  */    gp1->registered,                                   
  10391.           /* unread    */    newsrc_unread,                                     
  10392.           /* topnum    */    newsrc_topnum);                                    
  10393.                                                                                 
  10394.      if (gp1->article_vector == NULL                                            
  10395.       && gp1->saved_newsrc_line != NULL) {                                      
  10396.        strcat(newsrc_line," ");                                                 
  10397.                                                                                 
  10398.        if (!write_to_newsrc(np,newsrc_line,gp1->saved_newsrc_line))             
  10399.            write_ok = FALSE;                                                    
  10400.      }                                                                          
  10401.      else                                                                       
  10402.      if (gp1->article_vector_len == 0                                           
  10403.       || newsrc_unread == newsrc_count) {                                       
  10404.        strcat(newsrc_line," <0");                                               
  10405.      }                                                                          
  10406.      else {                                                                     
  10407.                                                                                 
  10408.        /*                                                             */        
  10409.        /* SEB started at 1 but since articles may expire before they  */        
  10410.        /* are read, I think it should start at the first "real" (fake)*/        
  10411.        /* article (and pretend everything prior was marked as read,   */        
  10412.        /* so they all collapse into one entry in the newsrc file).    */        
  10413.        /*                                                       -DDI  */        
  10414.                                                                                 
  10415.        /* OK, I used to start at 1 but since articles may expire AFTER*/        
  10416.        /* they have been read, it should start at the first real/fake */        
  10417.        /* article and pretend everything prior was marked as UNREAD,  */        
  10418.        /* mainly so that we can get rid of the "read_count".          */        
  10419.        /* It doesn't much matter whether expired articles are marked  */        
  10420.        /* as read or unread, because that's only relevant to articles */        
  10421.        /* that really exist anyhow.  They may not even be in the      */        
  10422.        /* article vector someday.                                     */        
  10423.        /* Notice that I also changed the definition of IV_READ and    */        
  10424.        /* IV_UNREAD so that missing articles are always called READ.  */        
  10425.                                                                                 
  10426. #define MORE_IV    (iv <= V_LENGTH(gp1))                                        
  10427. /*                                                                              
  10428.  * #define IV_READ    (gp1->article_vector[iv-1] == V_READ || \                 
  10429.  *                     gp1->article_vector[iv-1] == V_MISSING_READ)             
  10430.  * #define IV_UNREAD  (gp1->article_vector[iv-1] == V_UNREAD || \               
  10431.  *                    gp1->article_vector[iv-1] == V_MISSING_UNREAD)            
  10432.  */                                                                             
  10433. #define IV_READ    (V_STATUS(gp1,iv) == V_READ || \                             
  10434.                     V_STATUS(gp1,iv) == V_MISSING_READ)                         
  10435. #define IV_UNREAD  (V_STATUS(gp1,iv) == V_UNREAD || \                           
  10436.                     V_STATUS(gp1,iv) == V_MISSING_UNREAD)                       
  10437.                                                                                 
  10438.        iv = gp1->fake_first_article_number;                                     
  10439.                                                                                 
  10440.        /* iv=1; */                                                              
  10441.                                                                                 
  10442.        if (IV_UNREAD) {                                                         
  10443.          if (!write_to_newsrc(np,newsrc_line," <0")) write_ok = FALSE;          
  10444.        }                                                                        
  10445.        read0 = iv;                                                              
  10446.        read1 = NO_VALUE;                                                        
  10447.        read2 = NO_VALUE;                                                        
  10448.        for (;;) {                                                               
  10449.          while (MORE_IV && IV_UNREAD) iv++;                                     
  10450.          /* now we see the first of a series of read articles */                
  10451.          if (!MORE_IV) break;                                                   
  10452.          read1 = iv;                                                            
  10453.          /* so look for the last */                                             
  10454.          while (MORE_IV && IV_READ) iv++;                                       
  10455.          /* now we see the last of a series of read articles */                 
  10456.          read2 = iv-1;                                                          
  10457.          if (read1 == read0)         sprintf(newsrc_numb," <%d",read2);         
  10458.          else if (read1 == read2)    sprintf(newsrc_numb," %d" ,read2);         
  10459.          else if (read1 == read2-1)                                             
  10460.                   sprintf(newsrc_numb," %d %d", read1,read2);                   
  10461.          else     sprintf(newsrc_numb," |%d=%d",read1,read2);                   
  10462.          if (!write_to_newsrc(np,newsrc_line,newsrc_numb))                      
  10463.              write_ok = FALSE;                                                  
  10464.                                                                                 
  10465.        }                                                                        
  10466.      }                                                                          
  10467.      if (*newsrc_line) {                                                        
  10468.        if (fprintf(np->newsrc_file,"%s\n",newsrc_line) < 0)                     
  10469.            write_ok = FALSE;                                                    
  10470.      }                                                                          
  10471.    }                                                                            
  10472.  }                                                                              
  10473.                                                                                 
  10474.  /* Close the file, saving the contents. */                                     
  10475.                                                                                 
  10476.  if (!write_ok || ferror(np->newsrc_file)) {                                    
  10477.    fprintf(stderr,                                                              
  10478.            "%s: Error writing NEWSRC file.  Contents may be invalid.\n",        
  10479.            what_to_open);                                                       
  10480.  }                                                                              
  10481.                                                                                 
  10482.  if (fclose(np->newsrc_file) < 0) {                                             
  10483.    fprintf(stderr,                                                              
  10484.            "%s: Error closing NEWSRC file.  Contents may be invalid.\n",        
  10485.            what_to_open);                                                       
  10486.  }                                                                              
  10487.  np->newsrc_file = NULL;                                                        
  10488.                                                                                 
  10489.  return;                                                                        
  10490. }                                                                               
  10491.                                                                                 
  10492. ./   ADD NAME=NNMCONN,SSI=012A0054                                              
  10493.                                                                                 
  10494.  /********************************************************************/         
  10495.  /*                                                                  */         
  10496.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  10497.  /*                                                                  */         
  10498.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  10499.  /* including the implied warranties of merchantability and fitness, */         
  10500.  /* are expressly denied.                                            */         
  10501.  /*                                                                  */         
  10502.  /* Provided this copyright notice is included, this software may    */         
  10503.  /* be freely distributed and not offered for sale.                  */         
  10504.  /*                                                                  */         
  10505.  /* Changes or modifications may be made and used only by the maker  */         
  10506.  /* of same, and not further distributed.  Such modifications should */         
  10507.  /* be mailed to the author for consideration for addition to the    */         
  10508.  /* software and incorporation in subsequent releases.               */         
  10509.  /*                                                                  */         
  10510.  /********************************************************************/         
  10511.                                                                                 
  10512. #pragma  csect(code,  "NN@CONN ")                                               
  10513. #pragma  csect(static,"NN$CONN ")                                               
  10514. #include "nn.h"                                                                 
  10515.                                                                                 
  10516. #ifdef TCPIPV1                                                                  
  10517. #define REPORT_TCP_ERROR     /* */                                              
  10518. #endif                                                                          
  10519.                                                                                 
  10520. #ifdef TCPIPV2                                                                  
  10521. #define REPORT_TCP_ERROR     tcperror(np->nnserver)                             
  10522. #endif                                                                          
  10523.                                                                                 
  10524. /****** Internet address formatter. **********************************/         
  10525.                                                                                 
  10526. static void                                                                     
  10527. format_ip_address(ia,is)                                                        
  10528. IPADDRESS   ia;                                                                 
  10529. char       *is;                                                                 
  10530. {                                                                               
  10531.  char *cp = (char *)&ia;                                                        
  10532.                                                                                 
  10533.  sprintf(is,"%d.%d.%d.%d",*cp,*(cp+1),*(cp+2),*(cp+3));                         
  10534.  return;                                                                        
  10535. }                                                                               
  10536.                                                                                 
  10537. /****** Connect to news server. **************************************/         
  10538.                                                                                 
  10539. Bool                                                                            
  10540. NNMconn(np)                                                                     
  10541. Rstruc nncb *np;                                                                
  10542. {                                                                               
  10543.  char              *lp;                                                         
  10544.  char              *cp;                                                         
  10545.  struct hostent    *server_hp;                                                  
  10546.  struct sockaddr_in bindsock;       /* socket used by bind           */         
  10547.  struct sockaddr_in consock;        /* socket used by connect        */         
  10548.  int                bindsocklen;    /* size of bind socket           */         
  10549.  int                consocklen;     /* size of connect socket        */         
  10550.  int                bindrc;         /* the return code from bind     */         
  10551.  int                connrc;         /* the return code from connect  */         
  10552.  int                ip_part_1;                                                  
  10553.  int                ip_part_2;                                                  
  10554.  int                ip_part_3;                                                  
  10555.  int                ip_part_4;                                                  
  10556.                                                                                 
  10557.  if (np->connected_to_server) {                                                 
  10558.    NNMdisc(np);                /* Disconnect from news server */                
  10559.  }                                                                              
  10560.                                                                                 
  10561.  np->closing_connection = FALSE;                                                
  10562.                                                                                 
  10563.  if (!*np->nnserver) {                                                          
  10564.    ERR1("Server not defined;\                                                   
  10565. An NNTP server name must be defined before a connection can be made."           
  10566.        );                                                                       
  10567.    return FALSE;                                                                
  10568.  }                                                                              
  10569.                                                                                 
  10570.  for (cp = np->nnserver; *cp; cp++) *cp = toupper(*cp);                         
  10571.                                                                                 
  10572.  /* Get server name and address.                                                
  10573.   * The client name and address were gotten in NNMmain.                         
  10574.   */                                                                            
  10575.                                                                                 
  10576.  if (strchr(np->nnserver,'.') &&                                                
  10577.      np->nnserver[strspn(np->nnserver,".0123456789")] == '\0') {                
  10578.    ip_part_1 = ip_part_2 = ip_part_3 = ip_part_4 = 32767;                       
  10579.    strcpy(np->server_hostname, np->nnserver);                                   
  10580.    sscanf(np->nnserver,"%d.%d.%d.%d",&ip_part_1,                                
  10581.                                      &ip_part_2,                                
  10582.                                      &ip_part_3,                                
  10583.                                      &ip_part_4);                               
  10584.    if (ip_part_1 > 255 ||                                                       
  10585.        ip_part_2 > 255 ||                                                       
  10586.        ip_part_3 > 255 ||                                                       
  10587.        ip_part_4 > 255) {                                                       
  10588.      ERR2("Syntax error in server network address: %s", np->nnserver);          
  10589.      return FALSE;                                                              
  10590.    }                                                                            
  10591.    np->server_ip_address = (IPADDRESS) ((ip_part_1 << 24) +                     
  10592.                                         (ip_part_2 << 16) +                     
  10593.                                         (ip_part_3 <<  8) +                     
  10594.                                         (ip_part_4      ));                     
  10595.  }                                                                              
  10596.  else {                                                                         
  10597.    server_hp = gethostbyname(np->nnserver);                                     
  10598.    if (!server_hp) {                                                            
  10599.      ERR2(                                                                      
  10600. "Unknown host %s - gethostbyname() could not resolve the server name.",         
  10601.           np->nnserver);                                                        
  10602.      return FALSE;                                                              
  10603.    }                                                                            
  10604.    strcpy(np->server_hostname, server_hp->h_name);                              
  10605.    np->server_ip_address = *(IPADDRESS *)server_hp->h_addr;                     
  10606.  }                                                                              
  10607.                                                                                 
  10608.  format_ip_address(np->server_ip_address, np->server_ip_addrstr);               
  10609.  format_ip_address(np->client_ip_address, np->client_ip_addrstr);               
  10610.                                                                                 
  10611.  if (!np->batch_mode) {                                                         
  10612.    (void)NNMivput(np,"NNSERVER ",np->nnserver,-1);                              
  10613.    (void)NNMivput(np,"NNSERVIP ",np->server_ip_addrstr,-1);                     
  10614.    (void)NNMivput(np,"NNCLIENT ",np->nnclient,-1);                              
  10615.    (void)NNMivput(np,"NNCLIEIP ",np->client_ip_addrstr,-1);                     
  10616.  }                                                                              
  10617.                                                                                 
  10618.  consock.sin_family       = AF_INET;                                            
  10619.  consock.sin_port         = htons(NNTP_PORT_NUMBER);                            
  10620.  consock.sin_addr.s_addr  = np->server_ip_address;                              
  10621.                                                                                 
  10622.  bindsock.sin_family      = AF_INET;                                            
  10623.  bindsock.sin_port        = 0;                                                  
  10624.  bindsock.sin_addr.s_addr = np->client_ip_address;                              
  10625.                                                                                 
  10626.  np->socknum = socket(AF_INET, SOCK_STREAM, 0);                                 
  10627.  if (np->socknum < 0) {                                                         
  10628.    REPORT_TCP_ERROR;                                                            
  10629.    ERR2("TCP/IP error: socket() failed to make socket for server %s.",          
  10630.         np->nnserver);                                                          
  10631.    return FALSE;                                                                
  10632.  }                                                                              
  10633.                                                                                 
  10634.  bindsocklen = sizeof(bindsock);                                                
  10635.  bindrc = bind(np->socknum, &bindsock, bindsocklen);                            
  10636.  if (bindrc < 0) {                                                              
  10637.    REPORT_TCP_ERROR;                                                            
  10638.    ERR2("TCP/IP error: bind() failed to bind socket for server %s.",            
  10639.         np->nnserver);                                                          
  10640.    return FALSE;                                                                
  10641.  }                                                                              
  10642.                                                                                 
  10643.  if (np->batch_mode) {                                                          
  10644.    fprintf(np->batch_outfile,                                                   
  10645.            "Client %s (%s) connecting to news server on %s (%s)\n",             
  10646.            np->client_hostname,                                                 
  10647.            np->client_ip_addrstr,                                               
  10648.            np->server_hostname,                                                 
  10649.            np->server_ip_addrstr);                                              
  10650.  }                                                                              
  10651.  else {                                                                         
  10652.    (void)NNMispf(np,"CONTROL DISPLAY LOCK");                                    
  10653.    (void)NNMispf(np,"DISPLAY PANEL(NNMLCONN)");                                 
  10654.  }                                                                              
  10655.                                                                                 
  10656.  if (np->debug_file) {                                                          
  10657.    fprintf(np->debug_file,                                                      
  10658.            "Client %s (%s) connecting to news server on %s (%s)\n",             
  10659.            np->client_hostname,                                                 
  10660.            np->client_ip_addrstr,                                               
  10661.            np->server_hostname,                                                 
  10662.            np->server_ip_addrstr);                                              
  10663.  }                                                                              
  10664.                                                                                 
  10665.  consocklen = sizeof(consock);                                                  
  10666.  connrc = connect(np->socknum, &consock, consocklen);                           
  10667.                                                                                 
  10668.  if (connrc < 0) {                                                              
  10669.    REPORT_TCP_ERROR;                                                            
  10670.    ERR2("TCP/IP failure: connect() failed to connect to server %s.",            
  10671.         np->nnserver);                                                          
  10672.    return FALSE;                                                                
  10673.  }                                                                              
  10674.                                                                                 
  10675.  np->connected_to_server = TRUE;                                                
  10676.  np->time_to_go_home     = FALSE;                                               
  10677.  np->connection_broken   = FALSE;                                               
  10678.                                                                                 
  10679.  /* Now that the connection has been established, the news server               
  10680.   * is trying to send the first message:                                        
  10681.   * "200 servername blah blah blah - posting allowed"                           
  10682.   * or                                                                          
  10683.   * "201 servername blah blah blah - no posting allowed"                        
  10684.   * or                                                                          
  10685.   * "502 servername won't talk to you - goodbye"                                
  10686.   * Receive that message.  Otherwise disconnect will fail.                      
  10687.   *                                                                             
  10688.   * Read initial message from server.                                           
  10689.   */                                                                            
  10690.                                                                                 
  10691.  for (;;) {                                                                     
  10692.                                                                                 
  10693.    NNMssrvr(np);                             /* Start server read */            
  10694.                                                                                 
  10695.    if (!NNMgsrvl(np,&lp)) return FALSE;      /* Get server line */              
  10696.                                                                                 
  10697.    switch (np->nntp_message_num) {                                              
  10698.      case 200: np->posting_allowed = TRUE;   break;                             
  10699.      case 201: np->posting_allowed = FALSE;  break;                             
  10700.      case 502: NNMrperr(np);                /* Report procotol error */         
  10701.                np->connection_broken = TRUE;                                    
  10702.                NNMdisc(np);                 /* Clean up connection   */         
  10703.                return FALSE;                /* and abandon attempt   */         
  10704.     default:   NNMrperr(np);                /* Report protocol error */         
  10705.                continue;                    /* and ignore bad data   */         
  10706.    }                                                                            
  10707.                                                                                 
  10708.    break;                                                                       
  10709.                                                                                 
  10710.  }                                                                              
  10711.                                                                                 
  10712.  /* Clean up any other responses from server. */                                
  10713.                                                                                 
  10714.  NNMesrvr(np);                             /* End server read */                
  10715.                                                                                 
  10716.  /* If server needs authorization, try to provide it.  Note that we             
  10717.   * currently do this even on a reconnect.  A future optimization               
  10718.   * could be to save the authorization info so that we don't have               
  10719.   * to retrieve it all over again - as long as we don't retain                  
  10720.   * sensitive information in memory across ISPF displays.                       
  10721.   */                                                                            
  10722.                                                                                 
  10723.  if (NNMauth(np)) return TRUE;                 /* Send authinfo */              
  10724.  else return FALSE;                                                             
  10725.                                                                                 
  10726. }                                                                               
  10727.                                                                                 
  10728. ./   ADD NAME=NNMCOPY,SSI=01040044                                              
  10729.                                                                                 
  10730.  /********************************************************************/         
  10731.  /*                                                                  */         
  10732.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  10733.  /*                                                                  */         
  10734.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  10735.  /* including the implied warranties of merchantability and fitness, */         
  10736.  /* are expressly denied.                                            */         
  10737.  /*                                                                  */         
  10738.  /* Provided this copyright notice is included, this software may    */         
  10739.  /* be freely distributed and not offered for sale.                  */         
  10740.  /*                                                                  */         
  10741.  /* Changes or modifications may be made and used only by the maker  */         
  10742.  /* of same, and not further distributed.  Such modifications should */         
  10743.  /* be mailed to the author for consideration for addition to the    */         
  10744.  /* software and incorporation in subsequent releases.               */         
  10745.  /*                                                                  */         
  10746.  /********************************************************************/         
  10747.                                                                                 
  10748. #pragma  csect(code,  "NN@COPY ")                                               
  10749. #pragma  csect(static,"NN$COPY ")                                               
  10750. #include "nn.h"                                                                 
  10751.                                                                                 
  10752. /****** Copy string to non-volatile memory. **************************/         
  10753.                                                                                 
  10754. char *                                                                          
  10755. NNMcopy(np,string)                                                              
  10756. Rstruc nncb *np;                                                                
  10757. char        *string;                                                            
  10758. {                                                                               
  10759.  int         len = strlen(string);                                              
  10760.  char       *cp;                                                                
  10761.                                                                                 
  10762.  /* cheapo one malloc per string right now */                                   
  10763.                                                                                 
  10764.  GETMAIN(cp,char,len+1,"copy of string");                                       
  10765.  if (!cp) return NULL;                                                          
  10766.  strcpy(cp,string);                                                             
  10767.                                                                                 
  10768.  return cp;                                                                     
  10769. }                                                                               
  10770.                                                                                 
  10771. ./   ADD NAME=NNMDCAN,SSI=01050059                                              
  10772.                                                                                 
  10773.  /********************************************************************/         
  10774.  /*                                                                  */         
  10775.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  10776.  /*                                                                  */         
  10777.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  10778.  /*                                                                  */         
  10779.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  10780.  /* including the implied warranties of merchantability and fitness, */         
  10781.  /* are expressly denied.                                            */         
  10782.  /*                                                                  */         
  10783.  /* Provided this copyright notice is included, this software may    */         
  10784.  /* be freely distributed and not offered for sale.                  */         
  10785.  /*                                                                  */         
  10786.  /* Changes or modifications may be made and used only by the maker  */         
  10787.  /* of same, and not further distributed.  Such modifications should */         
  10788.  /* be mailed to the author for consideration for addition to the    */         
  10789.  /* software and incorporation in subsequent releases.               */         
  10790.  /*                                                                  */         
  10791.  /********************************************************************/         
  10792.                                                                                 
  10793. #pragma  csect(code,  "NN@DCAN ")                                               
  10794. #pragma  csect(static,"NN$DCAN ")                                               
  10795. #include "nn.h"                                                                 
  10796.                                                                                 
  10797. #define NEWSGROUPS_LENGTH   256-sizeof("Newsgroups: ")                          
  10798. #define SUBJECT_LENGTH      256-sizeof("Subject: ")                             
  10799. #define PATH_LENGTH         256-sizeof("Path: ")                                
  10800. #define FROM_LENGTH         256-sizeof("From: ")                                
  10801. #define APPROVED_LENGTH     256-sizeof("Approved: ")                            
  10802. #define CONTROL_LENGTH      256-sizeof("Control: ")                             
  10803. #define CANCEL_LENGTH       128-sizeof("cancel ")                               
  10804.                                                                                 
  10805. /*                                                                              
  10806.  * Note:  The algorithm for determining whether the user can cancel             
  10807.  *        an article is:                                                        
  10808.  *                                                                              
  10809.  *        (1) The article's FROM header must match the user's                   
  10810.  *            identification - i.e. userid@machine.host                         
  10811.  *                                                                              
  10812.  *        - OR -                                                                
  10813.  *                                                                              
  10814.  *        (2) if the article has an Approved: header, the user's                
  10815.  *            identification must match the Approved: header.                   
  10816.  *            The assumption is that the Approved: header is the                
  10817.  *            ID of the moderator of the newsgroup.                             
  10818.  *                                                                              
  10819.  */                                                                             
  10820.                                                                                 
  10821. /****** Collect additional article headers that we may need. *********/         
  10822.                                                                                 
  10823. static void                                                                     
  10824. get_more_headers(np,ap,from,approved)                                           
  10825. Rstruc nncb          *np;                                                       
  10826. Rstruc newsarticle   *ap;                                                       
  10827. char                 *from;                                                     
  10828. char                 *approved;                                                 
  10829. {                                                                               
  10830.  struct textline     *tp;                                                       
  10831.  struct texthdr      *thp;                                                      
  10832.  char                *cp;                                                       
  10833.  char                *newp;                                                     
  10834.  char                *colonp;                                                   
  10835.  int                  header_index;                                             
  10836.  char                 the_header[INTERNET_SIZE];                                
  10837.                                                                                 
  10838.  strcpy(from, "");                                                              
  10839.  strcpy(approved, "");                                                          
  10840.                                                                                 
  10841.  if (!ap) return;                                                               
  10842.                                                                                 
  10843.  /* Grovel through headers looking for what we want.                            
  10844.   */                                                                            
  10845.                                                                                 
  10846.  newp = NULL;                                                                   
  10847.  thp = &ap->thdr;                                                               
  10848.  strcpy(the_header,"");                                                         
  10849.  for (tp=thp->first_text_line; tp; tp=tp->next) {                               
  10850.    if (tp->text[0] == '\0') break;                                              
  10851.    if (tp->text[0] == ' '                                                       
  10852.     || tp->text[0] == '\t') {                                                   
  10853.      cp = tp->text + strspn(tp->text," \t");                                    
  10854.      if (*cp == '\0') break;                                                    
  10855.    }                                                                            
  10856.    else {                                                                       
  10857.      header_index = 0;                                                          
  10858.      colonp = strchr(tp->text,':');                                             
  10859.      if (!colonp) break;                                                        
  10860.      strcpy(the_header,"");                                                     
  10861.      for (cp = tp->text;cp<colonp;cp++) {                                       
  10862.        the_header[header_index++] = toupper(*cp);                               
  10863.      }                                                                          
  10864.      the_header[header_index] = '\0';                                           
  10865.      cp = colonp+1 + strspn(colonp+1," \t");                                    
  10866.    }                                                                            
  10867.    if      (EQUAL(the_header,"FROM"))                                           
  10868.            strncat(from,cp,FROM_LENGTH);                                        
  10869.    else if (EQUAL(the_header,"APPROVED"))                                       
  10870.            strncat(approved,cp,APPROVED_LENGTH);                                
  10871.  }                                                                              
  10872.                                                                                 
  10873.  /* Lowercase and strip trailing whitespace. */                                 
  10874.                                                                                 
  10875.  for (cp = from;  *cp; cp++) *cp = tolower(*cp);                                
  10876.  for (; cp > from && isspace(*cp-1); cp--);                                     
  10877.  *cp = '\0';                                                                    
  10878.                                                                                 
  10879.  for (cp = approved; *cp; cp++) *cp = tolower(*cp);                             
  10880.  for (; cp > approved && isspace(*cp-1); cp--);                                 
  10881.  *cp = '\0';                                                                    
  10882.                                                                                 
  10883.  return;                                                                        
  10884.                                                                                 
  10885. }                                                                               
  10886.                                                                                 
  10887. /****** Cancel a news article. ***************************************/         
  10888.                                                                                 
  10889. Bool                                                                            
  10890. NNMdcan(np,gp,ap)                                                               
  10891. Rstruc nncb         *np;                                                        
  10892. Rstruc newsgroup    *gp;                                                        
  10893. Rstruc newsarticle  *ap;                                                        
  10894. {                                                                               
  10895.  Bool                posted_ok     = FALSE;                                     
  10896.  Bool                post_error    = FALSE;                                     
  10897.  int                 l;                                                         
  10898.  int                 prc;                                                       
  10899.  char               *lp;                                                        
  10900.  char               *cp;                                                        
  10901.  char               *article_check_field;                                       
  10902.  struct tm          *nowtime;                                                   
  10903.  time_t              ltime;                                                     
  10904.  char                datestr[64];                                               
  10905.  char                midstr [64];                                               
  10906.  char                zuser   [9];                                               
  10907.  char                temp   [12];                                               
  10908.  char                post_message_id    [128];                                  
  10909.  char                post_subject       [SUBJECT_LENGTH];                       
  10910.  char                post_path          [PATH_LENGTH];                          
  10911.  char                post_newsgroups    [NEWSGROUPS_LENGTH];                    
  10912.  char                post_from          [FROM_LENGTH];                          
  10913.  char                post_control       [CONTROL_LENGTH];                       
  10914.  char                post_grape_nuts    [CANCEL_LENGTH];                        
  10915.  char                article_from       [FROM_LENGTH];                          
  10916.  char                article_approved   [APPROVED_LENGTH];                      
  10917.                                                                                 
  10918.  (void)NNMivget(np,"ZUSER ",zuser,sizeof(zuser));                               
  10919.                                                                                 
  10920.  /* assert ap is not null */                                                    
  10921.                                                                                 
  10922.  strcpy (post_newsgroups, gp->name);                                            
  10923.  sprintf(post_path,       "%s!%s", np->client_hostname, zuser);                 
  10924.  sprintf(post_grape_nuts, "cancel %s", ap->message_id);                         
  10925.  strcpy (post_subject,    post_grape_nuts);                                     
  10926.  strcpy (post_control,    post_grape_nuts);                                     
  10927.  sprintf(post_from,       "%s@%s", zuser, np->client_hostname);                 
  10928.                                                                                 
  10929.  for (cp = post_from; *cp; cp++) *cp = tolower(*cp);                            
  10930.                                                                                 
  10931.  get_more_headers(np,ap,article_from,article_approved);                         
  10932.  if ((cp=strpbrk(article_from,     " \t"))) *cp = '\0';                         
  10933.  if ((cp=strpbrk(article_approved, " \t"))) *cp = '\0';                         
  10934.                                                                                 
  10935.  if (*article_approved) article_check_field = article_approved;                 
  10936.  else                   article_check_field = article_from;                     
  10937.                                                                                 
  10938.  if (UNEQUAL(article_check_field, post_from)) {                                 
  10939.    ERR3("Cancel refused.  You, %s, are not %s.",                                
  10940.         post_from, article_check_field);                                        
  10941.    return FALSE;                                                                
  10942.  }                                                                              
  10943.                                                                                 
  10944.  /* Display confirmation panel containing the following info:                   
  10945.   *                                                                             
  10946.   * newsgroup name  = NNCGROUP                                                  
  10947.   * article number  = NNCNUM                                                    
  10948.   * article subject = NNCSUBJ                                                   
  10949.   * message ID      = NNCMSGID                                                  
  10950.   */                                                                            
  10951.                                                                                 
  10952.  if (!np->batch_mode) {                                                         
  10953.    sprintf(temp,"%d",ap->number);                                               
  10954.    (void)NNMivput(np,"NNCGROUP ",gp->name,         -1);                         
  10955.    (void)NNMivput(np,"NNCNUM   ",temp,             -1);                         
  10956.    (void)NNMivput(np,"NNCSUBJ  ",ap->subject,      -1);                         
  10957.    (void)NNMivput(np,"NNCMSGID ",ap->message_id,   -1);                         
  10958.    (void)NNMispf(np,"ADDPOP");                                                  
  10959.    (void)NNMispf(np,"DISPLAY PANEL(NNMPCAN)");                                  
  10960.    prc = np->ispfrc;                                                            
  10961.    (void)NNMispf(np,"REMPOP");                                                  
  10962.    if (prc > 0) { /* see if user pressed END */                                 
  10963.      WARN1("Operation cancelled, because you pressed END.");                    
  10964.      return FALSE;                                                              
  10965.    }                                                                            
  10966.  }                                                                              
  10967.                                                                                 
  10968.  /* Start posting here.                                                         
  10969.   *                                                                             
  10970.   * Me:     POST                                                                
  10971.   * Server: 340 send article to be posted.  End with <CR-LF>.<CR-LF>            
  10972.   *     or: 440 posting not allowed                                             
  10973.   * If 430...                                                                   
  10974.   *                                                                             
  10975.   * See RFC850 for details.                                                     
  10976.   *                                                                             
  10977.   * Me:     required_header: xxx                                                
  10978.   * ...                                                                         
  10979.   * Me:     <null line>                                                         
  10980.   * Me:     <text with leading periods hacked>                                  
  10981.   * Me:     .                                                                   
  10982.   * Server: 240 article posted OK                                               
  10983.   *     or: 441 posting failed                                                  
  10984.   */                                                                            
  10985.                                                                                 
  10986.   /* See NNMDPOST for more information. */                                      
  10987.                                                                                 
  10988.  /* Get current date and time, and generate a message id from it.               
  10989.   * If the message id is a duplicate, loop around until it isn't.               
  10990.   */                                                                            
  10991.                                                                                 
  10992.  do {                                                                           
  10993.                                                                                 
  10994.    time(<ime);                                                                
  10995.    nowtime = localtime(<ime);                                                 
  10996.    strftime(datestr,sizeof(datestr)-1,                                          
  10997.                     "%a, %d %b %Y %H:%M %Z",nowtime);                           
  10998.    strftime(midstr, sizeof(midstr)-1,                                           
  10999.                     "%Y%m%d%H%M%S",nowtime);                                    
  11000.                                                                                 
  11001.    sprintf(post_message_id,"<%s%s@%s>",                                         
  11002.                            midstr, zuser, np->client_hostname);                 
  11003.                                                                                 
  11004.  } while (strcmp(post_message_id,np->messageid) == 0);                          
  11005.                                                                                 
  11006.  strcpy(np->messageid,post_message_id);                                         
  11007.                                                                                 
  11008.  posted_ok = FALSE;                                                             
  11009.                                                                                 
  11010.  do {                                                                           
  11011.    strcpy(np->nntp_command,"POST");                                             
  11012.    if (!NNMsockt(np))     break;  /* Send socket command to server */           
  11013.    if (!NNMgsrvl(np,&lp)) break;  /* Get server line */                         
  11014.    switch (np->nntp_message_num) {                                              
  11015.      case 340: post_error = FALSE;                                              
  11016.                break;                                                           
  11017.      case 440: ERR2(                                                            
  11018.        "Cancellation failed.  Server %s did not accept the post.",              
  11019.                     np->nnserver);                                              
  11020.                post_error = TRUE;                                               
  11021.                break;                                                           
  11022.      default:  NNMrperr(np);       /* Report protocol error */                  
  11023.                post_error = TRUE;                                               
  11024.                break;                                                           
  11025.    }                                                                            
  11026.                                                                                 
  11027.    if (post_error) break;                                                       
  11028.                                                                                 
  11029.    /* Assert np->server_finished_replying == TRUE                               
  11030.     *     && np->receiving_text == TRUE                                         
  11031.     */                                                                          
  11032.                                                                                 
  11033.    sprintf(np->nntp_command,"Path: %s", post_path);                             
  11034.    if (!NNMsockt(np)) break;   /* Send socket command to server */              
  11035.                                                                                 
  11036.    sprintf(np->nntp_command,"Newsgroups: %s",post_newsgroups);                  
  11037.    if (!NNMsockt(np)) break;   /* Send socket command to server */              
  11038.                                                                                 
  11039.    sprintf(np->nntp_command,"Subject: %s",post_subject);                        
  11040.    if (!NNMsockt(np)) break;   /* Send socket command to server */              
  11041.                                                                                 
  11042.    sprintf(np->nntp_command,"Message-ID: %s", post_message_id);                 
  11043.    if (!NNMsockt(np)) break;   /* Send socket command to server */              
  11044.                                                                                 
  11045.    sprintf(np->nntp_command,"From: %s", post_from);                             
  11046.    if (!NNMsockt(np)) break;   /* Send socket command to server */              
  11047.                                                                                 
  11048.    sprintf(np->nntp_command,"Date: %s", datestr);                               
  11049.    if (!NNMsockt(np)) break;   /* Send socket command to server */              
  11050.                                                                                 
  11051.    if (*article_approved) {                                                     
  11052.      sprintf(np->nntp_command,"Approved: %s", article_approved);                
  11053.      if (!NNMsockt(np)) break;   /* Send socket command to server */            
  11054.    }                                                                            
  11055.                                                                                 
  11056.    sprintf(np->nntp_command,"Control: %s", post_control);                       
  11057.    if (!NNMsockt(np)) break;   /* Send socket command to server */              
  11058.                                                                                 
  11059.    strcpy(np->nntp_command,"");                                                 
  11060.    if (!NNMsockt(np)) break;   /* Send socket command to server */              
  11061.                                                                                 
  11062.    strcpy(np->nntp_command,post_grape_nuts);                                    
  11063.    if (!NNMsockt(np)) break;   /* Send socket command to server */              
  11064.                                                                                 
  11065.    strcpy(np->nntp_command,".");                                                
  11066.    if (!NNMsockt(np)) break;   /* Send socket command to server */              
  11067.                                                                                 
  11068.    if (!NNMgsrvl(np,&lp)) break;  /* Get server line */                         
  11069.    switch (np->nntp_message_num) {                                              
  11070.      case 240: posted_ok = TRUE;                                                
  11071.                break;                                                           
  11072.      case 441: NNMclrtx(np,NULL);               /* Clear text */                
  11073.                NNMouttx(np,np->server_buf,NULL);/* Output text line */          
  11074.                NNMvtx(np,NULL,NULL);            /* View text */                 
  11075.  ERR2("Cancel failed.  Server %s rejected the post.",np->nnserver);             
  11076.                posted_ok = FALSE;                                               
  11077.                break;                                                           
  11078.      default:  NNMrperr(np);       /* Report protocol error */                  
  11079.                posted_ok = FALSE;                                               
  11080.                break;                                                           
  11081.    }                                                                            
  11082.                                                                                 
  11083.    NNMesrvr(np);                   /* End server read */                        
  11084.                                                                                 
  11085.    break;                                                                       
  11086.                                                                                 
  11087.  } while(FALSE); /* one-time DO so I can break out of it */                     
  11088.                                                                                 
  11089.  if (!posted_ok) return FALSE;                                                  
  11090.                                                                                 
  11091.  WARN4("Cancel request for %s article %d sent to server %s.",                   
  11092.        gp->name, ap->number, np->nnserver);                                     
  11093.                                                                                 
  11094.  return TRUE;                                                                   
  11095. }                                                                               
  11096.                                                                                 
  11097. ./   ADD NAME=NNMDFAIL,SSI=01040032                                             
  11098.                                                                                 
  11099.  /********************************************************************/         
  11100.  /*                                                                  */         
  11101.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  11102.  /*                                                                  */         
  11103.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  11104.  /* including the implied warranties of merchantability and fitness, */         
  11105.  /* are expressly denied.                                            */         
  11106.  /*                                                                  */         
  11107.  /* Provided this copyright notice is included, this software may    */         
  11108.  /* be freely distributed and not offered for sale.                  */         
  11109.  /*                                                                  */         
  11110.  /* Changes or modifications may be made and used only by the maker  */         
  11111.  /* of same, and not further distributed.  Such modifications should */         
  11112.  /* be mailed to the author for consideration for addition to the    */         
  11113.  /* software and incorporation in subsequent releases.               */         
  11114.  /*                                                                  */         
  11115.  /********************************************************************/         
  11116.                                                                                 
  11117. #pragma  csect(code,  "NN@DFAIL")                                               
  11118. #pragma  csect(static,"NN$DFAIL")                                               
  11119. #include "nn.h"                                                                 
  11120.                                                                                 
  11121. /****** Retrieve allocation failure messages. ************************/         
  11122.                                                                                 
  11123. void                                                                            
  11124. NNMdfail(rc,p99)                                                                
  11125. int            rc;                                                              
  11126. __S99parms    *p99;                                                             
  11127. {                                                                               
  11128.  int           zero = 0;                                                        
  11129.  unsigned int  dfid = 0x40320000;                                               
  11130.  struct {                                                                       
  11131.          short first_level_msg_len;                                             
  11132.          short first_level_msg_offset;                                          
  11133.          char  first_level_msg[251];                                            
  11134.          short second_level_msg_len;                                            
  11135.          short second_level_msg_offset;                                         
  11136.          char  second_level_msg[251];                                           
  11137.         }      dfbuffer;                                                        
  11138.                                                                                 
  11139.  static int (*ikjeff18_pointer)() = NULL;                                       
  11140.                                                                                 
  11141. #ifndef FETCH                                                                   
  11142.  extern int *ikjeff18();                                                        
  11143. #endif                                                                          
  11144.                                                                                 
  11145.  if (!ikjeff18_pointer) {                                                       
  11146. #ifdef FETCH                                                                    
  11147.    ikjeff18_pointer = (int (*)())fetch("IKJEFF18");                             
  11148. #else                                                                           
  11149.    ikjeff18_pointer = (int (*)())ikjeff18;                                      
  11150. #endif                                                                          
  11151.  }                                                                              
  11152.                                                                                 
  11153.  dfbuffer.first_level_msg_len = 4;                                              
  11154.  dfbuffer.second_level_msg_len = 4;                                             
  11155.                                                                                 
  11156.  if (ikjeff18_pointer) {                                                        
  11157.    if ((*ikjeff18_pointer)(p99,&rc,&zero,&dfid,&zero,&dfbuffer)) {              
  11158.      fprintf(stderr,"IKJEFF18 returned a nonzero return code\n");               
  11159.    }                                                                            
  11160.    if (dfbuffer.first_level_msg_len > 0) {                                      
  11161.      fprintf(stderr,"%*.*s\n",                                                  
  11162.                     dfbuffer.first_level_msg_len-4,                             
  11163.                     dfbuffer.first_level_msg_len-4,                             
  11164.                     dfbuffer.first_level_msg);                                  
  11165.    }                                                                            
  11166.    if (dfbuffer.second_level_msg_len > 0) {                                     
  11167.      fprintf(stderr,"%*.*s\n",                                                  
  11168.                     dfbuffer.second_level_msg_len-4,                            
  11169.                     dfbuffer.second_level_msg_len-4,                            
  11170.                     dfbuffer.second_level_msg);                                 
  11171.    }                                                                            
  11172.  }                                                                              
  11173.  else {                                                                         
  11174. #ifdef FETCH                                                                    
  11175.    fprintf(stderr,"NNMVS: Cannot fetch IKJEFF18\n");                            
  11176. #else                                                                           
  11177.    fprintf(stderr,"Cannot call IKJEFF18, not linked with NNMVS\n");             
  11178. #endif                                                                          
  11179.  }                                                                              
  11180.  return;                                                                        
  11181. }                                                                               
  11182.                                                                                 
  11183. ./   ADD NAME=NNMDISC,SSI=01080037                                              
  11184.                                                                                 
  11185.  /********************************************************************/         
  11186.  /*                                                                  */         
  11187.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  11188.  /*                                                                  */         
  11189.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  11190.  /* including the implied warranties of merchantability and fitness, */         
  11191.  /* are expressly denied.                                            */         
  11192.  /*                                                                  */         
  11193.  /* Provided this copyright notice is included, this software may    */         
  11194.  /* be freely distributed and not offered for sale.                  */         
  11195.  /*                                                                  */         
  11196.  /* Changes or modifications may be made and used only by the maker  */         
  11197.  /* of same, and not further distributed.  Such modifications should */         
  11198.  /* be mailed to the author for consideration for addition to the    */         
  11199.  /* software and incorporation in subsequent releases.               */         
  11200.  /*                                                                  */         
  11201.  /********************************************************************/         
  11202.                                                                                 
  11203. #pragma  csect(code,  "NN@DISC ")                                               
  11204. #pragma  csect(static,"NN$DISC ")                                               
  11205. #include "nn.h"                                                                 
  11206.                                                                                 
  11207. /****** Disconnect from news server. *********************************/         
  11208.                                                                                 
  11209. void                                                                            
  11210. NNMdisc(np)                                                                     
  11211. Rstruc nncb *np;                                                                
  11212. {                                                                               
  11213.  int closerc;                                                                   
  11214.                                                                                 
  11215.  np->reconnect_in_progress = FALSE;                                             
  11216.  np->closing_connection    = TRUE;                                              
  11217.                                                                                 
  11218.  if (np->connection_broken) {                                                   
  11219.    if (np->debug_file) {                                                        
  11220.      fprintf(np->debug_file,                                                    
  11221.     "Client %s (%s) connection with news server on %s (%s) was lost\n",         
  11222.           np->client_hostname,                                                  
  11223.           np->client_ip_addrstr,                                                
  11224.           np->server_hostname,                                                  
  11225.           np->server_ip_addrstr);                                               
  11226.    }                                                                            
  11227.    if (np->batch_mode) {                                                        
  11228.      fprintf(np->batch_outfile,                                                 
  11229.     "Client %s (%s) connection with news server on %s (%s) was lost\n",         
  11230.           np->client_hostname,                                                  
  11231.           np->client_ip_addrstr,                                                
  11232.           np->server_hostname,                                                  
  11233.           np->server_ip_addrstr);                                               
  11234.    }                                                                            
  11235.    np->connected_to_server   = FALSE;                                           
  11236.  }                                                                              
  11237.  else {                                                                         
  11238.                                                                                 
  11239.    np->newsgroup_selected    = FALSE;                                           
  11240.    np->current_newsgroup     = NULL;                                            
  11241.                                                                                 
  11242.    /* In case of some kind of protocol error, don't let things hang. */         
  11243.                                                                                 
  11244.    NNMesrvr(np);         /* End server read */                                  
  11245.                                                                                 
  11246.    if (np->debug_file) {                                                        
  11247.      fprintf(np->debug_file,                                                    
  11248.           "Client %s (%s) disconnecting from news server on %s (%s)\n",         
  11249.           np->client_hostname,                                                  
  11250.           np->client_ip_addrstr,                                                
  11251.           np->server_hostname,                                                  
  11252.           np->server_ip_addrstr);                                               
  11253.    }                                                                            
  11254.                                                                                 
  11255.    if (np->batch_mode) {                                                        
  11256.      fprintf(np->batch_outfile,                                                 
  11257.           "Client %s (%s) disconnecting from news server on %s (%s)\n",         
  11258.           np->client_hostname,                                                  
  11259.           np->client_ip_addrstr,                                                
  11260.           np->server_hostname,                                                  
  11261.           np->server_ip_addrstr);                                               
  11262.    }                                                                            
  11263.    else {                                                                       
  11264.      (void)NNMivput(np,"NNSOLDER ",np->server_hostname,-1);                     
  11265.      (void)NNMivput(np,"NNSOLDIP ",np->server_ip_addrstr,-1);                   
  11266.      (void)NNMispf(np,"CONTROL DISPLAY LOCK");                                  
  11267.      (void)NNMispf(np,"DISPLAY PANEL(NNMLDISC)");                               
  11268.                                                                                 
  11269.    }                                                                            
  11270.                                                                                 
  11271.    /* Send the server a QUIT request.  In the past we got away without          
  11272.     * doing this.  However, this is important for one reason:                   
  11273.     * If the connection was lost before we attempt the disconnect,              
  11274.     * we want to know about it so that we don't attempt the close.              
  11275.     * The best way to find out is to try to send something.                     
  11276.     * Fortunately, the protocol fits right in with that need.                   
  11277.     */                                                                          
  11278.                                                                                 
  11279.    strcpy(np->nntp_command,"QUIT");                                             
  11280.    if (!NNMsockt(np)) return;      /* Send socket command to server */          
  11281.                                                                                 
  11282.    /* In case of some kind of protocol error, don't let things hang. */         
  11283.                                                                                 
  11284.    NNMesrvr(np);                   /* End server read */                        
  11285.                                                                                 
  11286.    np->connected_to_server   = FALSE;                                           
  11287.                                                                                 
  11288.    TCP_DEBUG_ON;                                                                
  11289.    closerc = close(np->socknum);                                                
  11290.    TCP_DEBUG_OFF;                                                               
  11291.                                                                                 
  11292.    if (closerc < 0) {                                                           
  11293.      ERR2("TCP/IP error: close() failed to disconnect from server %s.",         
  11294.           np->nnserver);                                                        
  11295.    }                                                                            
  11296.  }                                                                              
  11297.                                                                                 
  11298.  return;                                                                        
  11299. }                                                                               
  11300.                                                                                 
  11301. ./   ADD NAME=NNMDISPL,SSI=01080003                                             
  11302.                                                                                 
  11303.  /********************************************************************/         
  11304.  /*                                                                  */         
  11305.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  11306.  /*                                                                  */         
  11307.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  11308.  /*                                                                  */         
  11309.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  11310.  /* including the implied warranties of merchantability and fitness, */         
  11311.  /* are expressly denied.                                            */         
  11312.  /*                                                                  */         
  11313.  /* Provided this copyright notice is included, this software may    */         
  11314.  /* be freely distributed and not offered for sale.                  */         
  11315.  /*                                                                  */         
  11316.  /* Changes or modifications may be made and used only by the maker  */         
  11317.  /* of same, and not further distributed.  Such modifications should */         
  11318.  /* be mailed to the author for consideration for addition to the    */         
  11319.  /* software and incorporation in subsequent releases.               */         
  11320.  /*                                                                  */         
  11321.  /********************************************************************/         
  11322.                                                                                 
  11323. #pragma  csect(code,  "NN@DISPL")                                               
  11324. #pragma  csect(static,"NN$DISPL")                                               
  11325. #include "nn.h"                                                                 
  11326.                                                                                 
  11327. #define VL_BIT(X) ((unsigned int)(X) | 0x80000000)                              
  11328.                                                                                 
  11329. /****** Display ISPF panel. ******************************************/         
  11330.                                                                                 
  11331. int                                                                             
  11332. NNMdispl(np,pan8)                                                               
  11333. Rstruc nncb    *np;                                                             
  11334. char           *pan8;                                                           
  11335. {                                                                               
  11336.                                                                                 
  11337.  if (np->setmsg) {                                                              
  11338.    np->ispfrc = ISPLINK("DISPLAY ", pan8, VL_BIT("ISRZ002 "));                  
  11339.  }                                                                              
  11340.  else {                                                                         
  11341.    np->ispfrc = ISPLINK("DISPLAY ", VL_BIT(pan8));                              
  11342.  }                                                                              
  11343.                                                                                 
  11344.  if (np->ispfrc > 8) NNMierr(np);   /* display ISPF error */                    
  11345.                                                                                 
  11346.  np->setmsg = FALSE;                                                            
  11347.                                                                                 
  11348.  return np->ispfrc;                                                             
  11349. }                                                                               
  11350.                                                                                 
  11351. ./   ADD NAME=NNMDLANG,SSI=01570055                                             
  11352.                                                                                 
  11353.  /********************************************************************/         
  11354.  /*                                                                  */         
  11355.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  11356.  /*                                                                  */         
  11357.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  11358.  /*                                                                  */         
  11359.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  11360.  /* including the implied warranties of merchantability and fitness, */         
  11361.  /* are expressly denied.                                            */         
  11362.  /*                                                                  */         
  11363.  /* Provided this copyright notice is included, this software may    */         
  11364.  /* be freely distributed and not offered for sale.                  */         
  11365.  /*                                                                  */         
  11366.  /* Changes or modifications may be made and used only by the maker  */         
  11367.  /* of same, and not further distributed.  Such modifications should */         
  11368.  /* be mailed to the author for consideration for addition to the    */         
  11369.  /* software and incorporation in subsequent releases.               */         
  11370.  /*                                                                  */         
  11371.  /********************************************************************/         
  11372.                                                                                 
  11373. #pragma  csect(code,  "NN@DLANG")                                               
  11374. #pragma  csect(static,"NN$DLANG")                                               
  11375. #include "nn.h"                                                                 
  11376.                                                                                 
  11377. struct nndynarea {                                                              
  11378.                   struct newsgroup      *newsgroup;                             
  11379.                   char                   sel_attr;                              
  11380.                   char                   sel_field;                             
  11381.                   char                   name_attr;                             
  11382.                   char                   name[GROUP_NAME_SIZE];                 
  11383.                   char                   count_attr;                            
  11384.                   int                    count;                                 
  11385.                  };                                                             
  11386.                                                                                 
  11387. /****** Set date and time of last LIST or NEWGROUPS command. *********/         
  11388.                                                                                 
  11389. static void                                                                     
  11390. set_date_and_time(np)                                                           
  11391. Rstruc nncb      *np;                                                           
  11392. {                                                                               
  11393.   time_t          timeval;                                                      
  11394.   struct tm      *now;                                                          
  11395.                                                                                 
  11396.   time(&timeval);                                                               
  11397.   now = localtime(&timeval);                                                    
  11398.   now->tm_mon++;             /* adjust for # of months since Jan. */            
  11399.                                                                                 
  11400.   sprintf(np->lastNGdate, "%02d%02d%02d",                                       
  11401.                           now->tm_year, now->tm_mon, now->tm_mday);             
  11402.   sprintf(np->lastNGtime, "%02d%02d%02d",                                       
  11403.                           now->tm_hour, now->tm_min, now->tm_sec );             
  11404.   return;                                                                       
  11405. }                                                                               
  11406.                                                                                 
  11407. /****** Collect newsgroups using list from NEWSGROUPS request. *******/         
  11408.                                                                                 
  11409. static Bool                                                                     
  11410. collect_newsgroups(np,just_new_groups)                                          
  11411. Rstruc nncb         *np;                                                        
  11412. Fool                 just_new_groups;                                           
  11413. {                                                                               
  11414.  Rstruc newsgroup   *gp;                                                        
  11415.  struct newsgroup   *gpact;                                                     
  11416.  char               *lp;                                                        
  11417.  int                 list_first_article_number     = NO_VALUE;                  
  11418.  int                 list_last_article_number      = NO_VALUE;                  
  11419.  int                 ac;                                                        
  11420.  Bool                server_bug;                                                
  11421.  char                list_posting_allowed          = 'n';                       
  11422.  char                list_name[GROUP_NAME_SIZE]    = "";                        
  11423.  char                formatted_ac[12];                                          
  11424.                                                                                 
  11425.  /* np->new_newsgroup_count = 0; */                                             
  11426.  np->sending_text = TRUE;                                                       
  11427.  gpact = NULL;                                                                  
  11428.                                                                                 
  11429.  for (;;) {                                                                     
  11430.                                                                                 
  11431.    if (!NNMgsrvl(np,&lp))    return FALSE;   /* Get server line */              
  11432.    if (lp == NULL)           break;                                             
  11433.    if (strcmp(lp,".") == 0)  break;                                             
  11434.                                                                                 
  11435.    server_bug = FALSE;                                                          
  11436.                                                                                 
  11437.    if (just_new_groups) {                                                       
  11438.                                                                                 
  11439.      /* Extract fields from response to "NEWGROUPS" socket request.             
  11440.         Note that only newsgroup names are returned. */                         
  11441.                                                                                 
  11442.      if (1 != sscanf(np->nntp_message_text, "%s", list_name)) {                 
  11443.        NNMrbfm(np);   /* Report bad format message */                           
  11444.        return FALSE;                                                            
  11445.      }                                                                          
  11446.    }                                                                            
  11447.    else {                                                                       
  11448.                                                                                 
  11449.      /* Extract fields from response to "LIST" socket request.                  
  11450.         Note that no article count is provided. */                              
  11451.                                                                                 
  11452.      if (4 != sscanf(np->nntp_message_text, "%s %d %d %c",                      
  11453.                                  list_name,                                     
  11454.                                 &list_last_article_number,                      
  11455.                                 &list_first_article_number,                     
  11456.                                 &list_posting_allowed       )) {                
  11457.        NNMrbfm(np);   /* Report bad format message */                           
  11458.        return FALSE;                                                            
  11459.      }                                                                          
  11460.                                                                                 
  11461.      /* Fix up values in case of buggy server active file */                    
  11462.      if (list_first_article_number < 1) {                                       
  11463.        server_bug = TRUE;                                                       
  11464.        list_first_article_number = 1;                                           
  11465.      }                                                                          
  11466.      if (list_last_article_number < list_first_article_number - 1) {            
  11467.        server_bug = TRUE;                                                       
  11468.        list_last_article_number = list_first_article_number - 1;                
  11469.      }                                                                          
  11470.      if (server_bug) {                                                          
  11471.        fprintf(stderr,                                                          
  11472.          "Bad data from news server: %s %d %d %c\n",                            
  11473.                                      list_name,                                 
  11474.                                      list_last_article_number,                  
  11475.                                      list_first_article_number,                 
  11476.                                      list_posting_allowed);                     
  11477.      }                                                                          
  11478.    }                                                                            
  11479.                                                                                 
  11480.    if (just_new_groups) {                                                       
  11481.      ac = NO_VALUE;                                                             
  11482.      strcpy(formatted_ac,"");                                                   
  11483.    }                                                                            
  11484.    else {                                                                       
  11485.      ac = list_last_article_number - list_first_article_number + 1;             
  11486.      sprintf(formatted_ac,"%d",ac);                                             
  11487.    }                                                                            
  11488.    if (!np->batch_mode) {                                                       
  11489.      if (np->update_adding_newsgroups) {                                        
  11490.        (void)NNMivput(np,"NNLCOUNT ",formatted_ac,-1);                          
  11491.        (void)NNMivput(np,"NNLGROUP ",list_name,   -1);                          
  11492.        (void)NNMispf(np,"CONTROL DISPLAY LOCK");                                
  11493.        (void)NNMispf(np,"DISPLAY PANEL(NNMLADDG)");                             
  11494.      }                                                                          
  11495.    }                                                                            
  11496.                                                                                 
  11497.    gp = NNMaddng(np,list_name);           /* Add newsgroup */                   
  11498.                                                                                 
  11499.    if (just_new_groups) {                                                       
  11500.      np->new_newsgroup_count++;                                                 
  11501.      ClearGroupStatus(gp);                                                      
  11502.      SetNewGroup(gp);                                                           
  11503.      gp->registered = -1;                                                       
  11504.      continue;                                                                  
  11505.    }                                                                            
  11506.                                                                                 
  11507.    /* Put group in the proper "active file" order */                            
  11508.                                                                                 
  11509.    if (gpact) gpact->next2 = gp;                                                
  11510.    else       np->first_newsgroup_alt = gp;                                     
  11511.    gp->next2 = NULL;                                                            
  11512.    gpact = gp;                                                                  
  11513.                                                                                 
  11514.    OffNoSuchGroup(gp);    /* came from LIST, must exist now */                  
  11515.                                                                                 
  11516.    if (NullGroupStatus(gp)) {                                                   
  11517.      if (np->brand_new_newsrc) {                                                
  11518.        gp->registered = 0;     /* new news user, no autosubscribes */           
  11519.      }                                                                          
  11520.      else {                                                                     
  11521.        np->new_newsgroup_count++;                                               
  11522.        SetNewGroup(gp);                                                         
  11523.        gp->registered = -1;                                                     
  11524.      }                                                                          
  11525.    }                                                                            
  11526.                                                                                 
  11527.    /* If group previously present, either from NEWSRC file or                   
  11528.     * from a previous LIST or having been selected, then                        
  11529.     * adjust the counts of read and unread articles accordingly.                
  11530.     * Principle:  Selected is best, followed by Listed, followed                
  11531.     *          :  by FromNewsrc.                                                
  11532.     */                                                                          
  11533.                                                                                 
  11534.    if (GroupFromNewsrc(gp)                                                      
  11535.     || GroupFromNNTP(gp)) {          /* Adjust unread articles */               
  11536.      NNMadjua(np,gp,list_first_article_number,                                  
  11537.                     list_last_article_number,                                   
  11538.                     ac);                                                        
  11539.    }                                                                            
  11540.    else {                            /* new, never seen before */               
  11541.      gp->fake_unread_count          = ac;                                       
  11542.    }                                                                            
  11543.    if (!GroupFromNNTP(gp)) { /* new or only in NEWSRC before this */            
  11544.      gp->fake_article_count         = ac;                                       
  11545.      gp->fake_first_article_number  = list_first_article_number;                
  11546.      gp->fake_last_article_number   = list_last_article_number;                 
  11547.    }                                                                            
  11548.                                                                                 
  11549.    SetGroupListed(gp);                                                          
  11550.                                                                                 
  11551.    /* Since collect_newsgroups is called only for the LIST option,              
  11552.       we don't want to allocate article vectors yet. */                         
  11553.    /* (void)NNMallav(np,gp); -- Allocate article vector -- */                   
  11554.  }                                                                              
  11555.                                                                                 
  11556.  return TRUE;                                                                   
  11557.                                                                                 
  11558. }                                                                               
  11559.                                                                                 
  11560. /****** Display new newsgroups. **************************************/         
  11561.                                                                                 
  11562. static Bool                                                                     
  11563. display_new_newsgroups(np,just_new_groups)                                      
  11564. Rstruc nncb           *np;                                                      
  11565. Fool                   just_new_groups;                                         
  11566. {                                                                               
  11567.  Rstruc newsgroup     *gp;                                                      
  11568.  Rstruc nndynarea     *dp;                                                      
  11569.  struct nndynarea     *nndynarea_address;                                       
  11570.  int                   nndynarea_length;                                        
  11571.  int                   i;                                                       
  11572.  int                   prc;                                                     
  11573.  int                   nnlvl;                                                   
  11574.  int                   depth;                                                   
  11575.  int                   depthx80;                                                
  11576.  int                   zscrolln;                                                
  11577.  int                   topoff;                                                  
  11578.  int                   dynsize;                                                 
  11579.  char                 *cp;                                                      
  11580.  char                 *nndyna;                                                  
  11581.  char                 *nndyna_slice;                                            
  11582.  Bool                  retval;                                                  
  11583.  Bool                  is_max;                                                  
  11584.  char                  savechar;                                                
  11585.  char                  zverb    [9];                                            
  11586.  char                  zscrolla [9];                                            
  11587.  char                  zcmd    [81];                                            
  11588.                                                                                 
  11589.  retval = TRUE;                                                                 
  11590.                                                                                 
  11591.  if (np->new_newsgroup_count == 0) return TRUE;                                 
  11592.                                                                                 
  11593.  /* Allocate a block of "nndynarea" new-newsgroup structures. */                
  11594.                                                                                 
  11595.  GETMAIN(nndynarea_address, struct nndynarea,                                   
  11596.          np->new_newsgroup_count,"nndynarea");                                  
  11597.                                                                                 
  11598.  if (!nndynarea_address) return FALSE;                                          
  11599.                                                                                 
  11600.  nndynarea_length = np->new_newsgroup_count * sizeof(struct nndynarea);         
  11601.                                                                                 
  11602.  dp = nndynarea_address;                                                        
  11603.  i=0;                                                                           
  11604.  for (gp = np->first_newsgroup; gp; gp = gp->next) {                            
  11605.    if (NewGroup(gp)) {  /* if new newsgroup */                                  
  11606.      dp->newsgroup = gp;                                                        
  11607.      strcpy(dp->name,gp->name);                                                 
  11608.      dp->count = gp->fake_article_count;                                        
  11609.      dp++;                                                                      
  11610.      i++;                                                                       
  11611.    }                                                                            
  11612.  }                                                                              
  11613.                                                                                 
  11614.  if (i != np->new_newsgroup_count) {                                            
  11615.    fprintf(stderr,                                                              
  11616.  "Possible news server bug: %d new groups but %d NEWGROUPS\n",                  
  11617.           i, np->new_newsgroup_count);                                          
  11618.  }                                                                              
  11619.                                                                                 
  11620.  /* Preinitialize all newsgroups to unsubscribed. */                            
  11621.                                                                                 
  11622.  for (dp = nndynarea_address; i > 0; dp++, i--) {                               
  11623.    gp = dp->newsgroup;                                                          
  11624.    gp->registered = 0;                                                          
  11625.    OffNewGroup(gp);                                                             
  11626.    dp->sel_attr   = DATAIN_HIGH;                                                
  11627.    dp->sel_field  = ' ';                                                        
  11628.    dp->name_attr  = DATAOUT_LOW; /* since all unregistered init'ly */           
  11629.    dp->count_attr = DATAOUT_LOW;                                                
  11630.  }                                                                              
  11631.                                                                                 
  11632.  /* Display new newsgroups in dynamic area panel. */                            
  11633.                                                                                 
  11634.  (void)NNMispf(np,                                                              
  11635.        "PQUERY PANEL(NNMDNEWG) AREANAME(NNDYNA) DEPTH(NNDEPTH)");               
  11636.  if (np->ispfrc != 0) return FALSE;                                             
  11637.  depth = NNMiget(np,"NNDEPTH ");                                                
  11638.  depthx80 = depth * 80;                                                         
  11639.  topoff  = 0;                                                                   
  11640.  dynsize = 80*(np->new_newsgroup_count + depth) + 1;                            
  11641.                                                                                 
  11642.  GETMAIN(nndyna, char, dynsize, "NNDYNA buffer");                               
  11643.  if (!nndyna) return FALSE;                                                     
  11644.  memset(nndyna,' ',dynsize);                                                    
  11645.                                                                                 
  11646.  for (i = 0, cp=nndyna; i < np->new_newsgroup_count; i++, cp+=80) {             
  11647.    dp = &nndynarea_address[i];                                                  
  11648.    memset(cp,' ',80);                                                           
  11649.    cp[ 0] = dp->sel_attr;                                                       
  11650.    cp[ 1] = dp->sel_field;                                                      
  11651.    cp[ 2] = dp->name_attr;                                                      
  11652.    memcpy(&cp[3],dp->name,strlen(dp->name));                                    
  11653.    if (!just_new_groups) {                                                      
  11654.      cp[62] = dp->count_attr;                                                   
  11655.      sprintf(&cp[63],"%7d article%c",dp->count,                                 
  11656.                                      dp->count == 1 ? ' ' : 's');               
  11657.      cp[79] = ' ';                                                              
  11658.    }                                                                            
  11659.  }                                                                              
  11660.                                                                                 
  11661.  (void)NNMivput(np,"NNDN1ST ","YES",-1);                                        
  11662.                                                                                 
  11663.  do {                                                                           
  11664.    (void)NNMivput(np,"ZCMD ","",-1);                                            
  11665.    (void)NNMivput(np,"NNDYNA ",nndyna+topoff*80,depthx80);                      
  11666.    prc = NNMdispl(np,"NNMDNEWG");                                               
  11667.    if (prc > 8) break;                                                          
  11668.    (void)NNMivget(np,"ZCMD ",zcmd,sizeof(zcmd));                                
  11669.    if (zcmd[0] == 'Q'    /* QUIT   */                                           
  11670.     || zcmd[0] == 'C') { /* CANCEL */                                           
  11671.      retval = FALSE;                                                            
  11672.      break;                                                                     
  11673.    }                                                                            
  11674.    nnlvl = NNMiget(np,"NNLVL ");                                                
  11675.    nndyna_slice = nndyna + topoff*80;                                           
  11676.    savechar = nndyna_slice[depthx80];                                           
  11677.    (void)NNMivget(np,"NNDYNA ",nndyna_slice,depthx80);                          
  11678.    nndyna_slice[depthx80] = savechar;                                           
  11679.    for (i = 0, cp=nndyna_slice; i < nnlvl; i++, cp+=80) {                       
  11680.      if (i+topoff >= np->new_newsgroup_count) break;                            
  11681.      dp = &nndynarea_address[i+topoff];                                         
  11682.      gp = dp->newsgroup;                                                        
  11683.      dp->sel_field = ' ';                                                       
  11684.      switch (cp[1]) {                                                           
  11685.        case 'r':                                                                
  11686.        case 'R': gp->registered = 1;                                            
  11687.                  cp[1] = ' ';                                                   
  11688.                  cp[2] = DATAOUT_HIGH;                                          
  11689.                  break;                                                         
  11690.        case 'd':                                                                
  11691.        case 'D': gp->registered = 0;                                            
  11692.                  cp[1] = ' ';                                                   
  11693.                  cp[2] = DATAOUT_LOW;                                           
  11694.                  break;                                                         
  11695.        case 'q':                                                                
  11696.        case 'Q': NNMqng(np,gp);                                                 
  11697.                  cp[1] = ' ';                                                   
  11698.                  break;                                                         
  11699.        case ' ': break;                                                         
  11700.        default:                                                                 
  11701.                  cp[1] = '?';                                                   
  11702.                  cp[2] = DATAOUT_LOW;                                           
  11703.                  break;                                                         
  11704.      }                                                                          
  11705.    }                                                                            
  11706.    (void)NNMivget(np,"ZVERB ",zverb,sizeof(zverb));                             
  11707.    (void)NNMivget(np,"ZSCROLLA ",zscrolla,sizeof(zscrolla));                    
  11708.    zscrolln = NNMiget(np,"ZSCROLLN ");                                          
  11709.    is_max = EQUAL(zscrolla,"MAX");                                              
  11710.    if      (EQUAL(zverb,"DOWN")) {                                              
  11711.      if (is_max) topoff = np->new_newsgroup_count - nnlvl;                      
  11712.      else        topoff += zscrolln;                                            
  11713.    }                                                                            
  11714.    else if (EQUAL(zverb,"UP")) {                                                
  11715.      if (is_max) topoff = 0;                                                    
  11716.      else        topoff -= zscrolln;                                            
  11717.    }                                                                            
  11718.    if (topoff < 0)                                                              
  11719.        topoff = 0;                                                              
  11720.    if (topoff > np->new_newsgroup_count)                                        
  11721.        topoff = np->new_newsgroup_count;                                        
  11722.                                                                                 
  11723.  } while (prc == 0);                                                            
  11724.                                                                                 
  11725.  FREEMAIN(nndyna,"NNDYNA buffer");                                              
  11726.  FREEMAIN(nndynarea_address,"nndynarea");                                       
  11727.                                                                                 
  11728.  return retval;                                                                 
  11729. }                                                                               
  11730.                                                                                 
  11731. /****** Display bogus newsgroups. ************************************/         
  11732.                                                                                 
  11733. static Bool                                                                     
  11734. display_bogus_newsgroups(np)                                                    
  11735. Rstruc nncb           *np;                                                      
  11736. {                                                                               
  11737.  Rstruc newsgroup     *gp;                                                      
  11738.  Rstruc nndynarea     *dp;                                                      
  11739.  struct nndynarea     *nndynarea_address;                                       
  11740.  int                   nndynarea_length;                                        
  11741.  int                   i;                                                       
  11742.  int                   prc;                                                     
  11743.  int                   nnlvl;                                                   
  11744.  int                   depth;                                                   
  11745.  int                   depthx80;                                                
  11746.  int                   zscrolln;                                                
  11747.  int                   topoff;                                                  
  11748.  int                   dynsize;                                                 
  11749.  int                   bogus_newsgroup_count;                                   
  11750.  char                 *cp;                                                      
  11751.  char                 *k;                                                       
  11752.  char                 *nndyna;                                                  
  11753.  char                 *nndyna_slice;                                            
  11754.  Bool                  retval;                                                  
  11755.  Bool                  is_max;                                                  
  11756.  char                  savechar;                                                
  11757.  char                  zverb    [9];                                            
  11758.  char                  zscrolla [9];                                            
  11759.  char                  zcmd    [81];                                            
  11760.                                                                                 
  11761.  retval = TRUE;                                                                 
  11762.                                                                                 
  11763.  bogus_newsgroup_count = 0;                                                     
  11764.                                                                                 
  11765.  for (gp = np->first_newsgroup; gp; gp = gp->next) {                            
  11766.    if (BogusGroup(gp)) bogus_newsgroup_count++;                                 
  11767.  }                                                                              
  11768.                                                                                 
  11769.  if (bogus_newsgroup_count == 0) return TRUE;                                   
  11770.                                                                                 
  11771.  /* Allocate a block of "nndynarea" new-newsgroup structures. */                
  11772.                                                                                 
  11773.  GETMAIN(nndynarea_address, struct nndynarea,                                   
  11774.          bogus_newsgroup_count,"nndynarea");                                    
  11775.                                                                                 
  11776.  if (!nndynarea_address) return FALSE;                                          
  11777.                                                                                 
  11778.  nndynarea_length = bogus_newsgroup_count * sizeof(struct nndynarea);           
  11779.                                                                                 
  11780.  dp = nndynarea_address;                                                        
  11781.  i=0;                                                                           
  11782.  for (gp = np->first_newsgroup; gp; gp = gp->next) {                            
  11783.    if (BogusGroup(gp)) {                                                        
  11784.      SetNoSuchGroup(gp);                                                        
  11785.      OffGroupFromNewsrc(gp);                                                    
  11786.      dp->newsgroup = gp;                                                        
  11787.      strcpy(dp->name,gp->name);                                                 
  11788.      dp++;                                                                      
  11789.    }                                                                            
  11790.  }                                                                              
  11791.                                                                                 
  11792.  for(dp = nndynarea_address, i=bogus_newsgroup_count;                           
  11793.      i; dp++, i--) {                                                            
  11794.    dp->sel_attr   = DATAIN_HIGH;                                                
  11795.    dp->sel_field  = ' ';                                                        
  11796.    dp->name_attr  = DATAOUT_LOW; /* since all unregistered init'ly */           
  11797.  }                                                                              
  11798.                                                                                 
  11799.  /* Display bogus newsgroups in dynamic area panel. */                          
  11800.                                                                                 
  11801.  (void)NNMispf(np,                                                              
  11802.        "PQUERY PANEL(NNMDBOGG) AREANAME(NNDYNA) DEPTH(NNDEPTH)");               
  11803.  if (np->ispfrc != 0) return FALSE;                                             
  11804.  depth = NNMiget(np,"NNDEPTH ");                                                
  11805.  depthx80 = depth * 80;                                                         
  11806.  topoff  = 0;                                                                   
  11807.  dynsize = 80*(bogus_newsgroup_count + depth) + 1;                              
  11808.                                                                                 
  11809.  GETMAIN(nndyna, char, dynsize, "NNDYNA buffer");                               
  11810.  if (!nndyna) return FALSE;                                                     
  11811.  memset(nndyna,' ',dynsize);                                                    
  11812.                                                                                 
  11813.  for (i = 0, cp=nndyna; i < bogus_newsgroup_count; i++, cp+=80) {               
  11814.    dp = &nndynarea_address[i];                                                  
  11815.    memset(cp,' ',80);                                                           
  11816.    cp[ 0] = dp->sel_attr;                                                       
  11817.    cp[ 1] = dp->sel_field;                                                      
  11818.    cp[ 2] = dp->name_attr;                                                      
  11819.    strncpy(&cp[3],dp->name,67);                                                 
  11820.    if ((k=memchr(&cp[3],'\0',67))) *k = ' ';                                    
  11821.    cp[70] = DATAOUT_LOW;                                                        
  11822.    memcpy(&cp[71],"         ",9);                                               
  11823.  }                                                                              
  11824.                                                                                 
  11825.  (void)NNMivput(np,"NNDB1ST ","YES",-1);                                        
  11826.                                                                                 
  11827.  do {                                                                           
  11828.    (void)NNMivput(np,"ZCMD ","",-1);                                            
  11829.    (void)NNMivput(np,"NNDYNA ",nndyna+topoff*80,depthx80);                      
  11830.    prc = NNMdispl(np,"NNMDBOGG");                                               
  11831.    if (prc > 8) break;                                                          
  11832.    (void)NNMivget(np,"ZCMD ",zcmd,sizeof(zcmd));                                
  11833.    if (zcmd[0] == 'Q'    /* QUIT   */                                           
  11834.     || zcmd[0] == 'C') { /* CANCEL */                                           
  11835.      retval = FALSE;                                                            
  11836.      break;                                                                     
  11837.    }                                                                            
  11838.    nnlvl = NNMiget(np,"NNLVL ");                                                
  11839.    nndyna_slice = nndyna + topoff*80;                                           
  11840.    savechar = nndyna_slice[depthx80];                                           
  11841.    (void)NNMivget(np,"NNDYNA ",nndyna_slice,depthx80);                          
  11842.    nndyna_slice[depthx80] = savechar;                                           
  11843.    for (i = 0, cp=nndyna_slice; i < nnlvl; i++, cp+=80) {                       
  11844.      if (i+topoff >= bogus_newsgroup_count) break;                              
  11845.      dp = &nndynarea_address[i+topoff];                                         
  11846.      gp = dp->newsgroup;                                                        
  11847.      dp->sel_field = ' ';                                                       
  11848.      switch (cp[1]) {                                                           
  11849.        case 'd':                                                                
  11850.        case 'D': SetNoSuchGroup(gp);                                            
  11851.                  OffGroupFromNewsrc(gp);                                        
  11852.                  gp->fake_article_count         = 0;                            
  11853.                  gp->fake_first_article_number  = 0;                            
  11854.                  gp->fake_last_article_number   = 0;                            
  11855.                  gp->fake_unread_count          = 0;                            
  11856.                  gp->registered                 = 0;                            
  11857.                  cp[ 1] = ' ';                                                  
  11858.                  cp[ 2] = DATAOUT_LOW;                                          
  11859.                  cp[70] = DATAOUT_HIGH;                                         
  11860.                  memcpy(&cp[71],"Deleted  ",9);                                 
  11861.                  break;                                                         
  11862.        case 'k':                                                                
  11863.        case 'K': OffNoSuchGroup(gp);                                            
  11864.                  SetGroupFromNewsrc(gp);                                        
  11865.                  gp->fake_article_count         = 0;                            
  11866.                  gp->fake_first_article_number  = 0;                            
  11867.                  gp->fake_last_article_number   = 0;                            
  11868.                  gp->fake_unread_count          = 0;                            
  11869.                  cp[1] = ' ';                                                   
  11870.                  cp[70] = DATAOUT_HIGH;                                         
  11871.                  memcpy(&cp[71],"Kept     ",9);                                 
  11872.                  break;                                                         
  11873.        case 'q':                                                                
  11874.        case 'Q': NNMqng(np,gp);                                                 
  11875.                  cp[1] = ' ';                                                   
  11876.                  break;                                                         
  11877.        case ' ':                                                                
  11878.                  cp[1] = ' ';                                                   
  11879.                  cp[70] = DATAOUT_LOW;                                          
  11880.                  break;                                                         
  11881.        default:                                                                 
  11882.                  cp[1] = '?';                                                   
  11883.                  cp[70] = DATAOUT_HIGH;                                         
  11884.                  memcpy(&cp[71],"What?    ",9);                                 
  11885.                  break;                                                         
  11886.      }                                                                          
  11887.    }                                                                            
  11888.    (void)NNMivget(np,"ZVERB ",zverb,sizeof(zverb));                             
  11889.    (void)NNMivget(np,"ZSCROLLA ",zscrolla,sizeof(zscrolla));                    
  11890.    zscrolln = NNMiget(np,"ZSCROLLN ");                                          
  11891.    is_max = EQUAL(zscrolla,"MAX");                                              
  11892.    if      (EQUAL(zverb,"DOWN")) {                                              
  11893.      if (is_max) topoff = bogus_newsgroup_count - nnlvl;                        
  11894.      else        topoff += zscrolln;                                            
  11895.    }                                                                            
  11896.    else if (EQUAL(zverb,"UP")) {                                                
  11897.      if (is_max) topoff = 0;                                                    
  11898.      else        topoff -= zscrolln;                                            
  11899.    }                                                                            
  11900.    if (topoff < 0)                                                              
  11901.        topoff = 0;                                                              
  11902.    if (topoff > bogus_newsgroup_count)                                          
  11903.        topoff = bogus_newsgroup_count;                                          
  11904.                                                                                 
  11905.  } while (prc == 0);                                                            
  11906.                                                                                 
  11907.  FREEMAIN(nndyna,"NNDYNA buffer");                                              
  11908.  FREEMAIN(nndynarea_address,"nndynarea");                                       
  11909.                                                                                 
  11910.  return retval;                                                                 
  11911. }                                                                               
  11912.                                                                                 
  11913. /****** Option.....list all new newsgroups. **************************/         
  11914.                                                                                 
  11915. static Bool                                                                     
  11916. list_new(np)                                                                    
  11917. Rstruc nncb *np;                                                                
  11918. {                                                                               
  11919.  char       *lp;                                                                
  11920.  char        mmddyy[9];                                                         
  11921.  char        hhmmss[9];                                                         
  11922.                                                                                 
  11923.  lp = np->lastNGdate + strspn(np->lastNGdate,"0");                              
  11924.  if (*lp == '\0') {                                                             
  11925.    ERR1(                                                                        
  11926. "There is no previous date in the NEWSRC file.  Select the List option."        
  11927.        );                                                                       
  11928.    return FALSE;                                                                
  11929.  }                                                                              
  11930.                                                                                 
  11931.  sprintf(np->nntp_command, "NEWGROUPS %.6s %.6s",                               
  11932.                            np->lastNGdate, np->lastNGtime);                     
  11933.                                                                                 
  11934.  if (!NNMsockt(np)) return FALSE;   /* Send socket command to server */         
  11935.                                                                                 
  11936.  sprintf(mmddyy,"%2.2s/%2.2s/%2.2s",                                            
  11937.                 &np->lastNGdate[2],                                             
  11938.                 &np->lastNGdate[4],                                             
  11939.                 &np->lastNGdate[0]);                                            
  11940.  sprintf(hhmmss,"%2.2s:%2.2s:%2.2s",                                            
  11941.                 &np->lastNGtime[0],                                             
  11942.                 &np->lastNGtime[2],                                             
  11943.                 &np->lastNGtime[4]);                                            
  11944.                                                                                 
  11945.  if (np->update_adding_newsgroups) {                                            
  11946.    if (!np->batch_mode) {                                                       
  11947.      (void)NNMivput(np,"NNNGDT ",mmddyy,-1);                                    
  11948.      (void)NNMivput(np,"NNNGTM ",hhmmss,-1);                                    
  11949.      (void)NNMispf(np,"CONTROL DISPLAY LOCK");                                  
  11950.      (void)NNMispf(np,"DISPLAY PANEL(NNMLNEWG)");                               
  11951.    }                                                                            
  11952.  }                                                                              
  11953.                                                                                 
  11954.  if (!NNMgsrvl(np,&lp))             return FALSE; /* Get server line */         
  11955.  if (np->nntp_message_num != 231)   NNMrperr(np);                               
  11956.                                                                                 
  11957.  /* clear_newsgroups(np); */                                                    
  11958.                                                                                 
  11959.  if (!collect_newsgroups(np,TRUE)) return FALSE;                                
  11960.                                                                                 
  11961.  if (np->batch_mode) return TRUE;                                               
  11962.                                                                                 
  11963.  if (!display_new_newsgroups(np,TRUE)) return FALSE;                            
  11964.                                                                                 
  11965.  set_date_and_time(np);                                                         
  11966.                                                                                 
  11967.  if (np->new_newsgroup_count == 0) {                                            
  11968.    ERR3(                                                                        
  11969. "No new newsgroups since last use of L or N option, on %s %s",                  
  11970.         mmddyy, hhmmss);                                                        
  11971.    return FALSE;                                                                
  11972.  }                                                                              
  11973.                                                                                 
  11974.  return TRUE;                                                                   
  11975. }                                                                               
  11976.                                                                                 
  11977. /****** Option.....list all known newsgroups. ************************/         
  11978.                                                                                 
  11979. static Bool                                                                     
  11980. list_all(np)                                                                    
  11981. Rstruc nncb *np;                                                                
  11982. {                                                                               
  11983.  char       *lp;                                                                
  11984.                                                                                 
  11985.  strcpy(np->nntp_command,"LIST");                                               
  11986.  if (!NNMsockt(np)) return FALSE;   /* Send socket command to server */         
  11987.                                                                                 
  11988.  if (!np->batch_mode) {                                                         
  11989.    (void)NNMispf(np,"CONTROL DISPLAY LOCK");                                    
  11990.    (void)NNMispf(np,"DISPLAY PANEL(NNMLLIST)");                                 
  11991.  }                                                                              
  11992.                                                                                 
  11993.  if (!NNMgsrvl(np,&lp))             return FALSE; /* Get server line */         
  11994.  if (np->nntp_message_num != 215)   NNMrperr(np);                               
  11995.                                                                                 
  11996.  /* clear_newsgroups(np); */                                                    
  11997.                                                                                 
  11998.  if (!collect_newsgroups(np,FALSE)) return FALSE;                               
  11999.                                                                                 
  12000.  if (np->batch_mode) return TRUE;                                               
  12001.                                                                                 
  12002.  if (!display_new_newsgroups(np,FALSE)) return FALSE;                           
  12003.                                                                                 
  12004.  if (!display_bogus_newsgroups(np)) return FALSE;                               
  12005.                                                                                 
  12006.  set_date_and_time(np);                                                         
  12007.                                                                                 
  12008.  np->new_newsgroup_count = 0;                                                   
  12009.                                                                                 
  12010.  np->show_all_newsgroups = TRUE;                                                
  12011.                                                                                 
  12012.  return NNMvng(np);                           /* View newsgroups */             
  12013. }                                                                               
  12014.                                                                                 
  12015. /****** List all or new groups. **************************************/         
  12016.                                                                                 
  12017. Bool                                                                            
  12018. NNMdlang(np,option)                                                             
  12019. Rstruc nncb      *np;                                                           
  12020. enum list_option  option;                                                       
  12021. {                                                                               
  12022.                                                                                 
  12023.  switch (option) {                                                              
  12024.    case LIST_ALL:  return list_all(np);                                         
  12025.    case LIST_NEW:  return list_new(np);                                         
  12026.  }                                                                              
  12027.                                                                                 
  12028. }                                                                               
  12029.                                                                                 
  12030. ./   ADD NAME=NNMDMAIL,SSI=01270007                                             
  12031.                                                                                 
  12032.  /********************************************************************/         
  12033.  /*                                                                  */         
  12034.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  12035.  /*                                                                  */         
  12036.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  12037.  /*                                                                  */         
  12038.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  12039.  /* including the implied warranties of merchantability and fitness, */         
  12040.  /* are expressly denied.                                            */         
  12041.  /*                                                                  */         
  12042.  /* Provided this copyright notice is included, this software may    */         
  12043.  /* be freely distributed and not offered for sale.                  */         
  12044.  /*                                                                  */         
  12045.  /* Changes or modifications may be made and used only by the maker  */         
  12046.  /* of same, and not further distributed.  Such modifications should */         
  12047.  /* be mailed to the author for consideration for addition to the    */         
  12048.  /* software and incorporation in subsequent releases.               */         
  12049.  /*                                                                  */         
  12050.  /********************************************************************/         
  12051.                                                                                 
  12052. #pragma  csect(code,  "NN@DMAIL")                                               
  12053. #pragma  csect(static,"NN$DMAIL")                                               
  12054. #include "nn.h"                                                                 
  12055.                                                                                 
  12056. #define TO_LENGTH          256-sizeof("To: ")                                   
  12057. #define SUBJECT_LENGTH     256-sizeof("Subject: ")                              
  12058. #define FROM_LENGTH        256-sizeof("From: ")                                 
  12059. #define REPLY_TO_LENGTH    256-sizeof("Reply-to: ")                             
  12060.                                                                                 
  12061. /****** Determine to whom to reply, according to RFC822 standards ****/         
  12062.                                                                                 
  12063. static char *                                                                   
  12064. to_whom_to_reply(np,ap)                                                         
  12065. Rstruc nncb          *np;                                                       
  12066. Rstruc newsarticle   *ap;                                                       
  12067. {                                                                               
  12068.  struct textline     *tp;                                                       
  12069.  struct texthdr      *thp;                                                      
  12070.  char                *cp;                                                       
  12071.  char                *colonp;                                                   
  12072.  char                *resent_reply_to    = NULL;                                
  12073.  char                *resent_from        = NULL;                                
  12074.  char                *reply_to           = NULL;                                
  12075.  char                *from               = NULL;                                
  12076.  char                *resent_sender      = NULL;                                
  12077.  char                *sender             = NULL;                                
  12078.  int                  header_index;                                             
  12079.  char                 the_header[INTERNET_SIZE];                                
  12080.                                                                                 
  12081.  if (!ap) return "";                                                            
  12082.                                                                                 
  12083.  /* Since RFC1036 (Standard for Interchange of USENET Messages)                 
  12084.   * seems to imply that RFC822 header format is OK, we would                    
  12085.   * expect to do this.  In reality, headers like Reply-to: are                  
  12086.   * often filled with the name of the mailing list (e.g. BITNET).               
  12087.   * Therefore, the user needs to have the option of using                       
  12088.   * the From: header for replies.  Anyhow...                                    
  12089.   */                                                                            
  12090.                                                                                 
  12091.  /* Grovel through headers looking for likely candidates.  The official         
  12092.   * pecking order is:                                                           
  12093.   *                                                                             
  12094.   * Resent-Reply-To:                                                            
  12095.   * Resent-From:                                                                
  12096.   * Reply-To:                                                                   
  12097.   * From:                                                                       
  12098.   * Resent-Sender:                                                              
  12099.   * Sender:                                                                     
  12100.   *                                                                             
  12101.   * If none of the above, punt by returning a null string.                      
  12102.   *                                                                             
  12103.   * NOTE: There is no provision in this code for continued headers.             
  12104.   *       If you want to handle continued headers, use the code in              
  12105.   *       NNMDPOST as a model.  You will have to allocate your own              
  12106.   *       storage to hold 'em.                                                  
  12107.   */                                                                            
  12108.                                                                                 
  12109.  thp = &ap->thdr;                                                               
  12110.  strcpy(the_header,"");                                                         
  12111.  for (tp=thp->first_text_line; tp; tp=tp->next) {                               
  12112.    if (tp->text[0] == '\0') break;                                              
  12113.    if (tp->text[0] == ' '                                                       
  12114.     || tp->text[0] == '\t') {                                                   
  12115.      cp = tp->text + strspn(tp->text," \t");                                    
  12116.      if (*cp == '\0') break;                                                    
  12117.    }                                                                            
  12118.    else {                                                                       
  12119.      header_index = 0;                                                          
  12120.      colonp = strchr(tp->text,':');                                             
  12121.      if (!colonp) break;                                                        
  12122.      strcpy(the_header,"");                                                     
  12123.      for (cp = tp->text;cp<colonp;cp++) {                                       
  12124.        the_header[header_index++] = toupper(*cp);                               
  12125.      }                                                                          
  12126.      the_header[header_index] = '\0';                                           
  12127.    }                                                                            
  12128.    cp = colonp+1;                                                               
  12129.    while (*++cp && isspace(*cp));                                               
  12130.    if      (!strcmp(the_header,"RESENT-REPLY-TO")) resent_reply_to = cp;        
  12131.    else if (!strcmp(the_header,"RESENT-FROM"    )) resent_from     = cp;        
  12132.    else if (!strcmp(the_header,"REPLY-TO"       )) reply_to        = cp;        
  12133.    else if (!strcmp(the_header,"FROM"           )) from            = cp;        
  12134.    else if (!strcmp(the_header,"RESENT-SENDER"  )) resent_sender   = cp;        
  12135.    else if (!strcmp(the_header,"SENDER"         )) sender          = cp;        
  12136.  }                                                                              
  12137.                                                                                 
  12138.  return (resent_reply_to ? resent_reply_to :                                    
  12139.          resent_from     ? resent_from     :                                    
  12140.          reply_to        ? reply_to        :                                    
  12141.          from            ? from            :                                    
  12142.          resent_sender   ? resent_sender   :                                    
  12143.          sender          ? sender          :                                    
  12144.          "");                                                                   
  12145.                                                                                 
  12146. }                                                                               
  12147.                                                                                 
  12148. /****** Reply to a news article by mail, or just mail a message ******/         
  12149.                                                                                 
  12150. void                                                                            
  12151. NNMdmail(np,gp,ap)                                                              
  12152. Rstruc nncb         *np;                                                        
  12153. Rstruc newsgroup    *gp;                                                        
  12154. Rstruc newsarticle  *ap;                                                        
  12155. {                                                                               
  12156.  Bool                filled       = FALSE;                                      
  12157.  Bool                edit_error   = FALSE;                                      
  12158.  Bool                mail_error   = FALSE;                                      
  12159.  int                 l;                                                         
  12160.  int                 display_rc;                                                
  12161.  FILE               *efp          = NULL;                                       
  12162.  FILE               *mfp          = NULL;                                       
  12163.  FILE               *sfp          = NULL;                                       
  12164.  struct tm          *nowtime;                                                   
  12165.  char               *cp;                                                        
  12166.  time_t              ltime;                                                     
  12167.  char                datestr[64];                                               
  12168.  char                midstr [64];                                               
  12169.  char                zuser   [9];                                               
  12170.  char                tempdsn[L_tmpnam];                                         
  12171.  char                outpdsn[L_tmpnam];                                         
  12172.  char                editstr[40+L_tmpnam];                                      
  12173.  char                edit_profile     [  9];                                    
  12174.  char                signature_file   [ 64];                                    
  12175.  char                mail_message_id  [128];                                    
  12176.  char                zcmd             [ 81];                                    
  12177.  char                nnmailfr         [FROM_LENGTH];                            
  12178.  char                nnmailrt         [REPLY_TO_LENGTH];                        
  12179.  char                mail_from        [FROM_LENGTH];                            
  12180.  char                mail_to          [TO_LENGTH];                              
  12181.  char                mail_subject     [SUBJECT_LENGTH];                         
  12182.  char                mailline         [260];                                    
  12183.  char                sigline          [260];                                    
  12184.  char                mail_command     [260];                                    
  12185.                                                                                 
  12186.  (void)NNMivget(np,"ZUSER ",zuser,sizeof(zuser));                               
  12187.                                                                                 
  12188.  if (ap) {                                                                      
  12189.    if (strlen(ap->subject) >= 3 &&                                              
  12190.        (!memcmp(ap->subject,"Re:",3) ||                                         
  12191.         !memcmp(ap->subject,"re:",3) ||                                         
  12192.         !memcmp(ap->subject,"RE:",3)))   strcpy(mail_subject,"");               
  12193.    else                                  strcpy(mail_subject,"Re: ");           
  12194.    strncat(mail_subject, ap->subject, sizeof(mail_subject));                    
  12195.  }                                                                              
  12196.  else strcpy(mail_subject,"");                                                  
  12197.                                                                                 
  12198.  (void)NNMivput(np,"NNMAILTO ",to_whom_to_reply(np,ap),-1);                     
  12199.  (void)NNMivput(np,"NNMAILOT ",(ap ? ap->from : "")   ,-1);                     
  12200.  (void)NNMivput(np,"NNMAILSJ ",mail_subject,-1);                                
  12201.                                                                                 
  12202.  strcpy(outpdsn,"");                                                            
  12203.                                                                                 
  12204.  /* Can't use this - C/370 compiler bug... */                                   
  12205.  /* strcpy(tempdsn,ap ? "" : np->maildsn); */                                   
  12206.                                                                                 
  12207.  if (ap) strcpy(tempdsn,"");                                                    
  12208.  else    strcpy(tempdsn,np->maildsn);                                           
  12209.                                                                                 
  12210.  if (!*tempdsn) {                                                               
  12211.    if (!tmpnam(tempdsn)) {                                                      
  12212.      ERR1(                                                                      
  12213. "A temporary data set name could not be created.  tmpnam() error."              
  12214.          );                                                                     
  12215.      return;                                                                    
  12216.    }                                                                            
  12217.    if (!(efp = OPEN_TEXT_FILE_FOR_WRITE(tempdsn))) {                            
  12218.      ERR2("Error trying to open temp data set: %s", tempdsn);                   
  12219.      return;                                                                    
  12220.    }                                                                            
  12221.    if (fclose(efp) < 0) {                                                       
  12222.      ERR2("Error trying to close temp data set: %s", tempdsn);                  
  12223.      return;                                                                    
  12224.    }                                                                            
  12225.    efp = NULL;                                                                  
  12226.    if (!ap) strcpy(np->maildsn,tempdsn);                                        
  12227.  }                                                                              
  12228.                                                                                 
  12229.  while (NNMdispl(np,"NNMQMAIL") == 0) {                                         
  12230.                                                                                 
  12231.    NNMivget(np,"NNMAILTO ",mail_to,        sizeof(mail_to)        );            
  12232.    NNMivget(np,"NNMAILSJ ",mail_subject,   sizeof(mail_subject)   );            
  12233.    NNMivget(np,"NNMAILRT ",nnmailrt,       sizeof(nnmailrt)       );            
  12234.    NNMivget(np,"NNMAILFR ",nnmailfr,       sizeof(nnmailfr)       );            
  12235.    NNMivget(np,"NNMAILSF ",signature_file, sizeof(signature_file) );            
  12236.    NNMivget(np,"NNEDPROF ",edit_profile,   sizeof(edit_profile)   );            
  12237.                                                                                 
  12238.    (void)NNMivput(np,"NNTEMPDS ",tempdsn,-1);                                   
  12239.                                                                                 
  12240.    /* Insure that we can access the signature file, if given. */                
  12241.                                                                                 
  12242.    if (*signature_file) {                                                       
  12243.      if (!(sfp=fopen(signature_file,"r"))) {                                    
  12244.        perror(signature_file);                                                  
  12245.        ERR2("Cannot open signature file %s.  Check that it is valid.",          
  12246.              signature_file);                                                   
  12247.        continue;                                                                
  12248.      }                                                                          
  12249.    }                                                                            
  12250.    else sfp = NULL;                                                             
  12251.                                                                                 
  12252.    /* Fill temporary data set with message to which we are replying,            
  12253.     * if this is a REPLY request,                                               
  12254.     * and the contents of the signature file if any.                            
  12255.     */                                                                          
  12256.                                                                                 
  12257.    if (!filled) {                                                               
  12258.      if (!(efp = OPEN_TEXT_FILE_FOR_WRITE(tempdsn))) {                          
  12259.        ERR2("Error trying to open temp data set: %s", tempdsn);                 
  12260.        continue;                                                                
  12261.      }                                                                          
  12262.      if (ap) {                                                                  
  12263.        np->extract_file            = efp;                                       
  12264.        np->extract_appending       = FALSE;                                     
  12265.        np->extract_separator_line  = FALSE;                                     
  12266.        np->extract_tab_expanding   = TRUE;                                      
  12267.        np->following_up            = TRUE;                                      
  12268.        fprintf(efp, "In article %s,\n%s writes:\n\n",                           
  12269.                     ap->message_id, ap->from);                                  
  12270.        (void)NNMxtx(np,ap,FALSE);            /* Extract article text */         
  12271.        np->following_up            = FALSE;                                     
  12272.        if (ferror(efp)) {                                                       
  12273.          ERR2("Error trying to write to temp data set: %s", tempdsn);           
  12274.          continue;                                                              
  12275.        }                                                                        
  12276.      }                                                                          
  12277.                                                                                 
  12278.      if (sfp) {                                                                 
  12279.        fprintf(efp,"\n--\n",efp);                                               
  12280.        if (ferror(efp)) np->extract_write_error = TRUE;                         
  12281.        for (;;) {                                                               
  12282.          fgets(sigline,sizeof(sigline),sfp);                                    
  12283.          if (ferror(sfp)) {                                                     
  12284.            ERR2(                                                                
  12285.   "Cannot read from signature file %s.  Check that it is valid.",               
  12286.                 signature_file);                                                
  12287.            break;                                                               
  12288.          }                                                                      
  12289.          if (feof(sfp)) break;                                                  
  12290.          if ((cp=strchr(sigline,'\n'))) *cp = '\0';                             
  12291.          l = strlen(sigline);                                                   
  12292.          fwrite(sigline,(l>251 ? 251 : l),1,efp);                               
  12293.          if (ferror(efp)) {                                                     
  12294.            np->extract_write_error = TRUE; break;                               
  12295.          }                                                                      
  12296.          if (fputc('\n',efp) == EOF) {                                          
  12297.            np->extract_write_error = TRUE; break;                               
  12298.          }                                                                      
  12299.        }                                                                        
  12300.        (void)fclose(sfp);                                                       
  12301.        if (ferror(efp)) {                                                       
  12302.          ERR2("Error trying to write to temp data set: %s", tempdsn);           
  12303.          continue;                                                              
  12304.        }                                                                        
  12305.      }                                                                          
  12306.      if (fclose(efp) < 0) {                                                     
  12307.        ERR2("Error trying to close temp data set: %s", tempdsn);                
  12308.        continue;                                                                
  12309.      }                                                                          
  12310.      filled = TRUE;                                                             
  12311.    }                                                                            
  12312.                                                                                 
  12313.    efp = NULL;                                                                  
  12314.                                                                                 
  12315. #ifndef I370                                                                    
  12316.    sprintf(editstr,"EDIT DATASET(%s) PROFILE(%s)",tempdsn,edit_profile);        
  12317. #else                                                                           
  12318.    sprintf(editstr, "EDIT DATASET('%s') PROFILE(%s)",                           
  12319.            tempdsn+4, edit_profile);                                            
  12320. #endif                                                                          
  12321.                                                                                 
  12322.    edit_error = FALSE;                                                          
  12323.                                                                                 
  12324.    (void)NNMispf(np,editstr);                                                   
  12325.    switch (np->ispfrc) {                                                        
  12326.      case 0:  edit_error = FALSE;            break;                             
  12327.      case 4:  ERR1(                                                             
  12328. "Edit ended without SAVE, mailing cancelled.  Reenter and SAVE to mail."        
  12329.                   );                         continue;                          
  12330.      default: edit_error = TRUE;             break;                             
  12331.    }                                                                            
  12332.                                                                                 
  12333.    if (edit_error) continue;                                                    
  12334.                                                                                 
  12335.    /* Confirm mailing. */                                                       
  12336.                                                                                 
  12337.    (void)NNMispf (np,"ADDPOP ");                                                
  12338.    display_rc = NNMdispl(np,"NNMPCONM");                                        
  12339.    (void)NNMispf (np,"REMPOP ");                                                
  12340.    (void)NNMivget(np,"ZCMD ",zcmd,sizeof(zcmd));                                
  12341.    if (display_rc > 0) continue;                                                
  12342.    if (*zcmd == 'c' || *zcmd == 'C') {                                          
  12343.      (void)NNMivput(np,"ZCMD ","",-1);                                          
  12344.      ERR1("Mailing cancelled by user.  Reenter EDIT and SAVE to mail.");        
  12345.      return;                                                                    
  12346.    }                                                                            
  12347.                                                                                 
  12348.    if (!(efp = fopen(tempdsn,"r"))) {                                           
  12349.      ERR2("Error trying to open temp data set: %s", tempdsn);                   
  12350.      continue;                                                                  
  12351.    }                                                                            
  12352.                                                                                 
  12353.    /* Get current date and time, and generate a message id from it.             
  12354.     * If the message id is a duplicate, loop around until it isn't.             
  12355.     */                                                                          
  12356.                                                                                 
  12357.    do {                                                                         
  12358.                                                                                 
  12359.      time(<ime);                                                              
  12360.      nowtime = localtime(<ime);                                               
  12361.      strftime(datestr,sizeof(datestr)-1,                                        
  12362.                       "%a, %d %b %Y %H:%M %Z",nowtime);                         
  12363.      strftime(midstr, sizeof(midstr)-1,                                         
  12364.                       "%Y%m%d%H%M%S",nowtime);                                  
  12365.                                                                                 
  12366.      sprintf(mail_message_id,"<%s%s@%s>",                                       
  12367.                              midstr,                                            
  12368.                              zuser,                                             
  12369.                              np->client_hostname);                              
  12370.                                                                                 
  12371.    } while (strcmp(mail_message_id,np->messageid) == 0);                        
  12372.                                                                                 
  12373.    strcpy(np->messageid,mail_message_id);                                       
  12374.                                                                                 
  12375.    if (!*outpdsn) {                                                             
  12376.      if (!tmpnam(outpdsn)) {                                                    
  12377.      ERR1(                                                                      
  12378. "A temporary data set name could not be created.  tmpnam() error."              
  12379.          );                                                                     
  12380.        continue;                                                                
  12381.      }                                                                          
  12382.    }                                                                            
  12383.                                                                                 
  12384.    if (!(mfp = OPEN_TEXT_FILE_FOR_WRITE(outpdsn))) {                            
  12385.      ERR2("Error trying to open temp data set: %s", outpdsn);                   
  12386.      continue;                                                                  
  12387.    }                                                                            
  12388.                                                                                 
  12389.    do {                                                                         
  12390.                                                                                 
  12391.      if (*nnmailfr)                                                             
  12392.           sprintf(mail_from,"%s@%s (%s)",                                       
  12393.                             zuser, np->client_hostname, nnmailfr);              
  12394.      else sprintf(mail_from,"%s@%s",                                            
  12395.                             zuser, np->client_hostname);                        
  12396.                                                                                 
  12397.      fprintf(mfp,"From: %s\n",       mail_from);                                
  12398.      fprintf(mfp,"To: %s\n",         mail_to);                                  
  12399.      fprintf(mfp,"Subject: %s\n",    mail_subject);                             
  12400.      fprintf(mfp,"Date: %s\n",       datestr);                                  
  12401.      fprintf(mfp,"Message-ID: %s\n", mail_message_id);                          
  12402.                                                                                 
  12403.      /* insert optional headers here */                                         
  12404.                                                                                 
  12405.      if (*nnmailrt) {                                                           
  12406.        fprintf(mfp,"Reply-to: %s\n", nnmailrt);                                 
  12407.      }                                                                          
  12408.                                                                                 
  12409.      fprintf(mfp,"Sender: MVS NNTP News Reader <%s@%s>\n",                      
  12410.                  NNMVS_NAME, np->client_hostname);                              
  12411.                                                                                 
  12412.      if (ap) {                                                                  
  12413.     /*                                                                          
  12414.      * Uncomment this section when a references field in the                    
  12415.      * newsarticle struct is added.  Will require total recompilation           
  12416.      *                                                                          
  12417.      * if (ap->references)                                                      
  12418.      *  sprintf(np->nntp_command,"References: %s %s\n",                         
  12419.      *          ap->references, ap->message_id);                                
  12420.      * else                                                                     
  12421.      */                                                                         
  12422.        fprintf(mfp,"References: %s\n",ap->message_id);                          
  12423.      }                                                                          
  12424.                                                                                 
  12425.      /* By rights the following should be a null line.                          
  12426.       * However, C/370 always makes it a single blank anyhow,                   
  12427.       * and even if it were a null line (as SAS/C does),                        
  12428.       * UCLA/MAIL would break.  Hence, make it a single blank.                  
  12429.       */                                                                        
  12430.                                                                                 
  12431.      fprintf(mfp," \n");                                                        
  12432.                                                                                 
  12433.      while (!feof(efp) && !ferror(efp)) {                                       
  12434.        fgets(mailline,sizeof(mailline),efp);                                    
  12435.        if (feof(efp)) break;                                                    
  12436.        if (ferror(efp)) break;                                                  
  12437.        if (*mailline && mailline[l=strlen(mailline)-1] == '\n')                 
  12438.           mailline[l] = '\0';                                                   
  12439.        fprintf(mfp,"%s\n",mailline);                                            
  12440.      }                                                                          
  12441.                                                                                 
  12442.      fclose(mfp);                                                               
  12443.                                                                                 
  12444. #ifndef I370                                                                    
  12445.      sprintf(mail_command,"NNMMAIL %s %s",outpdsn,mail_to);                     
  12446. #else                                                                           
  12447.      sprintf(mail_command,"NNMMAIL '%s' %s",outpdsn+4,mail_to);                 
  12448. #endif                                                                          
  12449.                                                                                 
  12450.      if (NNMtso(mail_command) != 0) {                                           
  12451.        ERR1("Mail failed.  Failure trying to send your message.");              
  12452.        mail_error = TRUE;                                                       
  12453.      }                                                                          
  12454.                                                                                 
  12455.      remove(outpdsn);                                                           
  12456.                                                                                 
  12457.      break;                                                                     
  12458.                                                                                 
  12459.    } while(FALSE); /* one-time DO so I can break out of it */                   
  12460.                                                                                 
  12461.    if (!mail_error) {                                                           
  12462.      (void)NNMivput(np,"NNMAILID ",mail_message_id,-1);                         
  12463.      WARN1("Your mail message has been sent, presumably successfully.");        
  12464.      break;                                                                     
  12465.    }                                                                            
  12466.                                                                                 
  12467.  }                                                                              
  12468.                                                                                 
  12469.  if (!efp) return;                                                              
  12470.                                                                                 
  12471.  if (ferror(efp)) {                                                             
  12472.    ERR2("Error trying to read from temp data set: %s", tempdsn);                
  12473.  }                                                                              
  12474.                                                                                 
  12475.  if (fclose(efp) < 0) {                                                         
  12476.    ERR2("Error trying to close temp data set: %s", tempdsn);                    
  12477.  }                                                                              
  12478.                                                                                 
  12479.  if (ap) {                                                                      
  12480.    if (remove(tempdsn) < 0) {                                                   
  12481.      ERR2("Error trying to delete temp data set: %s", tempdsn);                 
  12482.    }                                                                            
  12483.  }                                                                              
  12484.                                                                                 
  12485.  return;                                                                        
  12486. }                                                                               
  12487.                                                                                 
  12488. ./   ADD NAME=NNMDMENU,SSI=012C0009                                             
  12489.                                                                                 
  12490.  /********************************************************************/         
  12491.  /*                                                                  */         
  12492.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  12493.  /*                                                                  */         
  12494.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  12495.  /*                                                                  */         
  12496.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  12497.  /* including the implied warranties of merchantability and fitness, */         
  12498.  /* are expressly denied.                                            */         
  12499.  /*                                                                  */         
  12500.  /* Provided this copyright notice is included, this software may    */         
  12501.  /* be freely distributed and not offered for sale.                  */         
  12502.  /*                                                                  */         
  12503.  /* Changes or modifications may be made and used only by the maker  */         
  12504.  /* of same, and not further distributed.  Such modifications should */         
  12505.  /* be mailed to the author for consideration for addition to the    */         
  12506.  /* software and incorporation in subsequent releases.               */         
  12507.  /*                                                                  */         
  12508.  /********************************************************************/         
  12509.                                                                                 
  12510. #pragma  csect(code,  "NN@DMENU")                                               
  12511. #pragma  csect(static,"NN$DMENU")                                               
  12512. #include "nn.h"                                                                 
  12513.                                                                                 
  12514. /****** Report invalid or unsupported selection. *********************/         
  12515.                                                                                 
  12516. static Bool                                                                     
  12517. display_invalid_selection(np)                                                   
  12518. Rstruc nncb *np;                                                                
  12519. {                                                                               
  12520.  ERR1("Your selection is not valid.  Please choose an available one.");         
  12521.  return FALSE;                                                                  
  12522. }                                                                               
  12523.                                                                                 
  12524. /****** Option.....set user options. *********************************/         
  12525.                                                                                 
  12526. static Bool                                                                     
  12527. display_set_options(np)                                                         
  12528. Rstruc nncb *np;                                                                
  12529. {                                                                               
  12530.  NNMdsopt(np,NULL);                                                             
  12531.  return FALSE;                                                                  
  12532. }                                                                               
  12533.                                                                                 
  12534. /****** Option.....execute NNTP commands. ****************************/         
  12535.                                                                                 
  12536. static Bool                                                                     
  12537. display_nntp(np)                                                                
  12538. Rstruc nncb *np;                                                                
  12539. {                                                                               
  12540.  NNMdnntp(np,NULL);                                                             
  12541.  return FALSE;                                                                  
  12542. }                                                                               
  12543.                                                                                 
  12544. /****** Option.....list ALL newsgroups from NEWSRC file. *************/         
  12545.                                                                                 
  12546. static Bool                                                                     
  12547. display_all_from_newsrc(np)                                                     
  12548. Rstruc nncb        *np;                                                         
  12549. {                                                                               
  12550.                                                                                 
  12551.  if (np->newsgroup_order == NNTP_LIST_ORDER)                                    
  12552.     np->newsgroup_order = ALPHABETICAL_ORDER;                                   
  12553.  np->show_all_newsgroups = TRUE;                                                
  12554.  return NNMvng(np);                           /* View newsgroups */             
  12555. }                                                                               
  12556.                                                                                 
  12557. /****** Option.....list REGISTERED newsgroups from NEWSRC file. ******/         
  12558.                                                                                 
  12559. static Bool                                                                     
  12560. display_reg_from_newsrc(np)                                                     
  12561. Rstruc nncb        *np;                                                         
  12562. {                                                                               
  12563.  char               nnrgans[4];                                                 
  12564.  int                prc;                                                        
  12565.  Rstruc newsgroup  *gp;                                                         
  12566.  struct countdown   cd;                                                         
  12567.                                                                                 
  12568.  /* Before viewing the newsgroup list, go through all the newsgroups            
  12569.   * and get the status of each one by selecting it.                             
  12570.   * This is controlled by the NNREGNNG variable if an option was                
  12571.   * preselected and Y or N was specified for REGISTERSTATUS.                    
  12572.   */                                                                            
  12573.                                                                                 
  12574.  nnrgans[0] = 'P';                                                              
  12575.  if (np->preselection) {                                                        
  12576.    switch (np->nnregnng[0]) {                                                   
  12577.      case 'N': nnrgans[0] = 'N'; break;                                         
  12578.      case 'Y': nnrgans[0] = 'Y'; break;                                         
  12579.    }                                                                            
  12580.  }                                                                              
  12581.                                                                                 
  12582.  if (nnrgans[0] == 'P') {                                                       
  12583.                                                                                 
  12584.    /* Display panel asking if user really wants to do this. */                  
  12585.                                                                                 
  12586.    (void)NNMispf(np,"ADDPOP");                                                  
  12587.    prc = NNMdispl(np,"NNMPGREG");                                               
  12588.    (void)NNMispf(np,"REMPOP");                                                  
  12589.    if (prc > 0) return FALSE;  /* see if user pressed END */                    
  12590.    (void)NNMivget(np,"NNRGANS ",nnrgans,sizeof(nnrgans));                       
  12591.                                                                                 
  12592.  }                                                                              
  12593.                                                                                 
  12594.  if (nnrgans[0] == 'Y') {                                                       
  12595.    if (np->updatefreq >= 0) {                                                   
  12596.      cd.do_update = TRUE;                                                       
  12597.      cd.done      = 0;                                                          
  12598.      cd.to_do     = 0;                                                          
  12599.      for (gp=np->first_newsgroup;gp;gp=gp->next) {                              
  12600.        if (gp->registered) cd.to_do++;                                          
  12601.      }                                                                          
  12602.    }                                                                            
  12603.    for (gp=np->first_newsgroup;gp;gp=gp->next) {                                
  12604.      if (gp->registered) {                                                      
  12605.        if (np->updatefreq >= 0) {                                               
  12606.          (void)NNMivput(np,"NNLGROUP ",gp->name,-1);                            
  12607.          /*                                                                     
  12608.           * (void)NNMispf(np,"CONTROL DISPLAY LOCK");                           
  12609.           * (void)NNMispf(np,"DISPLAY PANEL(NNMLRETG)");                        
  12610.           */                                                                    
  12611.          NNMupdt(np,&cd,np->updatefreq > 0 ? "NNMLRET2" : "NNMLRET3");          
  12612.        }                                                                        
  12613.        do_newsgroup_by_address(np,gp);                                          
  12614.      }                                                                          
  12615.    }                                                                            
  12616.  }                                                                              
  12617.                                                                                 
  12618.  if (np->newsgroup_order == NNTP_LIST_ORDER)                                    
  12619.     np->newsgroup_order = ALPHABETICAL_ORDER;                                   
  12620.  np->show_all_newsgroups = FALSE;                                               
  12621.  return NNMvng(np);                           /* View newsgroups */             
  12622. }                                                                               
  12623.                                                                                 
  12624. /****** Option.....list all newsgroups. ******************************/         
  12625.                                                                                 
  12626. static Bool                                                                     
  12627. list_all_newsgroups(np)                                                         
  12628. Rstruc nncb       *np;                                                          
  12629. {                                                                               
  12630.  return NNMdlang(np,LIST_ALL);                                                  
  12631. }                                                                               
  12632.                                                                                 
  12633. /****** Option.....list new newsgroups. ******************************/         
  12634.                                                                                 
  12635. static Bool                                                                     
  12636. list_new_newsgroups(np)                                                         
  12637. Rstruc nncb       *np;                                                          
  12638. {                                                                               
  12639.  return NNMdlang(np,LIST_NEW);                                                  
  12640. }                                                                               
  12641.                                                                                 
  12642. /****** Option.....retrieve articles from specified newsgroup. *******/         
  12643.                                                                                 
  12644. static Bool                                                                     
  12645. display_specific_newsgroup(np)                                                  
  12646. Rstruc nncb       *np;                                                          
  12647. {                                                                               
  12648.  Rstruc newsgroup *gp;                                                          
  12649.  char             *cp;                                                          
  12650.                                                                                 
  12651.  np->newsgroup_selected = FALSE;                                                
  12652.                                                                                 
  12653.  /* The ISPF variable NNGROUPI contains the name of the newsgroup. */           
  12654.                                                                                 
  12655.  if (NNMivget(np,"NNGROUPI ",np->nngroup,sizeof(np->nngroup))) {                
  12656.                                                                                 
  12657.    for (cp = np->nngroup; *cp; cp++) *cp = tolower(*cp);                        
  12658.                                                                                 
  12659.    (void)NNMivput(np,"NNGROUP ",np->nngroup,-1);                                
  12660.                                                                                 
  12661.    gp = do_newsgroup_by_name(np,np->nngroup);                                   
  12662.    if (gp == NULL) {                                                            
  12663.      (void)NNMivput(np,"NNCURSOR ","NNGROUPI ",8);                              
  12664.      return FALSE;                                                              
  12665.    }                                                                            
  12666.                                                                                 
  12667.    np->show_all_articles       = TRUE;                                          
  12668.    np->bypass_header_retrieval = FALSE;                                         
  12669.    np->unread_articles_only    = FALSE;                                         
  12670.                                                                                 
  12671.    (void)NNMvar(np,gp);              /* View articles */                        
  12672.  }                                                                              
  12673.                                                                                 
  12674.  return TRUE;                                                                   
  12675. }                                                                               
  12676.                                                                                 
  12677. /****** Display menu. ************************************************/         
  12678.                                                                                 
  12679. enum display_retval                                                             
  12680. NNMdmenu(np,selfunp)                                                            
  12681. Rstruc nncb   *np;                                                              
  12682. Bool        (**selfunp)();                                                      
  12683. {                                                                               
  12684.  char        zcmd[72];                                                          
  12685.  char        new_nnserver[MAXHOSTNAMELEN];                                      
  12686.  Bool        server_changed = FALSE;                                            
  12687.                                                                                 
  12688.  *selfunp = NULL;                                                               
  12689.                                                                                 
  12690.  if (np->preselection) {                                                        
  12691.    zcmd[0] = toupper(np->preselection);                                         
  12692.    np->preselection = SELECTION_EXIT;                                           
  12693.    (void)NNMispf(np,                                                            
  12694.                  "VGET (NNSERVER NNNEWSRC NNREGNNG NNGROUPI) PROFILE");         
  12695.  }                                                                              
  12696.  else {                                                                         
  12697.                                                                                 
  12698.    (void)NNMispf(np,"CONTROL DISPLAY REFRESH");                                 
  12699.                                                                                 
  12700.    (void)NNMdispl(np,"NNM     ");                                               
  12701.    if (np->ispfrc > 8) return DISPLAY_FAILURE;                                  
  12702.    if (np->ispfrc > 0) return DISPLAY_EXIT;                                     
  12703.    if (!NNMivget(np,"ZCMD ",zcmd,sizeof(zcmd))) return DISPLAY_ERROR;           
  12704.  }                                                                              
  12705.                                                                                 
  12706.  if (!NNMivget(np,"NNSERVER ",new_nnserver,MAXHOSTNAMELEN)                      
  12707.   || !NNMivget(np,"NNREGNNG ",np->nnregnng,sizeof(np->nnregnng))) {             
  12708.    np->preselection = '\0';                                                     
  12709.    return DISPLAY_ERROR;                                                        
  12710.  }                                                                              
  12711.                                                                                 
  12712.  /* Note: selection functions return Bool value indicating whether              
  12713.   *       to rewrite NEWSRC file (TRUE) or not (FALSE).                         
  12714.   *       See NNMMAIN for implementation of this.                               
  12715.   */                                                                            
  12716.                                                                                 
  12717.  switch (zcmd[0]) {                                                             
  12718.    case SELECTION_ALL:   *selfunp = display_all_from_newsrc;    break;          
  12719.    case SELECTION_REG:   *selfunp = display_reg_from_newsrc;    break;          
  12720.    case SELECTION_GROUP: *selfunp = display_specific_newsgroup; break;          
  12721.    case SELECTION_LIST:  *selfunp = list_all_newsgroups;        break;          
  12722.    case SELECTION_NEWG:  *selfunp = list_new_newsgroups;        break;          
  12723.    case SELECTION_NNTP:  *selfunp = display_nntp;               break;          
  12724.    case SELECTION_OPTS:  *selfunp = display_set_options;        break;          
  12725.    case SELECTION_EXIT:  return DISPLAY_EXIT;                                   
  12726.    default:              *selfunp = display_invalid_selection;                  
  12727.                          np->preselection = '\0';                               
  12728.                          return DISPLAY_REPEAT;                                 
  12729.  };                                                                             
  12730.                                                                                 
  12731.  /* If user typed a different server name, or this is the first time,           
  12732.     connect to the requested server. */                                         
  12733.                                                                                 
  12734.  if (UNEQUAL(new_nnserver,np->nnserver)) {                                      
  12735.    server_changed = TRUE;                                                       
  12736.  }                                                                              
  12737.  if (np->connected_to_server == FALSE ||                                        
  12738.      np->connection_broken   == TRUE  ||                                        
  12739.      server_changed) {                                                          
  12740.    strcpy(np->nnserver,new_nnserver);                                           
  12741.    if (!NNMconn(np)) {                  /* Connect to news server */            
  12742.      (void)NNMivput(np,"NNCURSOR ","NNSERVER ",8);                              
  12743.      *selfunp = NULL;                                                           
  12744.      np->preselection = '\0';                                                   
  12745.      return DISPLAY_ERROR;                                                      
  12746.    }                                                                            
  12747.  }                                                                              
  12748.                                                                                 
  12749.  return DISPLAY_REPEAT;                                                         
  12750. }                                                                               
  12751.                                                                                 
  12752. ./   ADD NAME=NNMDNG,SSI=010A0016                                               
  12753.                                                                                 
  12754.  /********************************************************************/         
  12755.  /*                                                                  */         
  12756.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  12757.  /*                                                                  */         
  12758.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  12759.  /*                                                                  */         
  12760.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  12761.  /* including the implied warranties of merchantability and fitness, */         
  12762.  /* are expressly denied.                                            */         
  12763.  /*                                                                  */         
  12764.  /* Provided this copyright notice is included, this software may    */         
  12765.  /* be freely distributed and not offered for sale.                  */         
  12766.  /*                                                                  */         
  12767.  /* Changes or modifications may be made and used only by the maker  */         
  12768.  /* of same, and not further distributed.  Such modifications should */         
  12769.  /* be mailed to the author for consideration for addition to the    */         
  12770.  /* software and incorporation in subsequent releases.               */         
  12771.  /*                                                                  */         
  12772.  /********************************************************************/         
  12773.                                                                                 
  12774. #pragma  csect(code,  "NN@DNG  ")                                               
  12775. #pragma  csect(static,"NN$DNG  ")                                               
  12776. #include "nn.h"                                                                 
  12777.                                                                                 
  12778. /****** Process newsgroup by name or address. ************************/         
  12779.                                                                                 
  12780. struct newsgroup *                                                              
  12781. NNMdng(np,gp,group)                                                             
  12782. Rstruc nncb         *np;                                                        
  12783. Rstruc newsgroup    *gp;                                                        
  12784. char                *group;                                                     
  12785. {                                                                               
  12786.  char               *p;                                                         
  12787.  int                 newsgroup_article_count         = NO_VALUE;                
  12788.  int                 newsgroup_first_article_number  = NO_VALUE;                
  12789.  int                 newsgroup_last_article_number   = NO_VALUE;                
  12790.  char                newsgroup_name[GROUP_NAME_SIZE] = "";                      
  12791.                                                                                 
  12792.  /* Tell the server to select the requested newsgroup. */                       
  12793.                                                                                 
  12794.  if (!NNMestng(np,gp ? gp->name : group)) /* Establish newsgroup */             
  12795.     return NULL;                                                                
  12796.                                                                                 
  12797.  /* From the response to the "GROUP xxx" NNTP selection request,                
  12798.     extract the number of articles and the numbers of the                       
  12799.     first and last articles, as well as the actual name. */                     
  12800.                                                                                 
  12801.  if (4 != sscanf(np->nntp_message_text, "%d %d %d %s",                          
  12802.                               &newsgroup_article_count,                         
  12803.                               &newsgroup_first_article_number,                  
  12804.                               &newsgroup_last_article_number,                   
  12805.                                newsgroup_name                    )) {           
  12806.    NNMrbfm(np);   /* Report bad format message */                               
  12807.    return NULL;                                                                 
  12808.  }                                                                              
  12809.                                                                                 
  12810.  for (p=newsgroup_name;*p;p++) *p = tolower(*p);                                
  12811.                                                                                 
  12812.  if (!gp) gp = NNMaddng(np,newsgroup_name);   /* Add newsgroup */               
  12813.                                                                                 
  12814.  OffNoSuchGroup(gp);                                                            
  12815.  OffGroupError(gp);                                                             
  12816.                                                                                 
  12817.                                                                                 
  12818.  if (GroupFromNewsrc(gp)                                                        
  12819.   || GroupFromNNTP(gp)) {          /* Adjust unread articles */                 
  12820.    NNMadjua(np,gp,newsgroup_first_article_number,                               
  12821.                   newsgroup_last_article_number,                                
  12822.                   newsgroup_article_count);                                     
  12823.  }                                                                              
  12824.  if (!GroupSelected(gp)) {                                                      
  12825.    gp->fake_article_count         = newsgroup_article_count;                    
  12826.    gp->fake_first_article_number  = newsgroup_first_article_number;             
  12827.    if (newsgroup_last_article_number > gp->fake_last_article_number)            
  12828.        gp->fake_last_article_number = newsgroup_last_article_number;            
  12829.  }                                                                              
  12830.  if (NullGroupStatus(gp)) {        /* newsgroup never seen before */            
  12831.    gp->fake_unread_count = newsgroup_article_count;                             
  12832.  }                                                                              
  12833.                                                                                 
  12834.  if (!GroupFromNewsrc(gp)) {                                                    
  12835.    gp->registered = 0;                                                          
  12836.  }                                                                              
  12837.                                                                                 
  12838.  SetGroupSelected(gp);                                                          
  12839.                                                                                 
  12840.  (void)NNMallav(np,gp);     /* Allocate article vector */                       
  12841.                                                                                 
  12842.  return gp;                                                                     
  12843. }                                                                               
  12844.                                                                                 
  12845. ./   ADD NAME=NNMDNNTP,SSI=010D0047                                             
  12846.                                                                                 
  12847.  /********************************************************************/         
  12848.  /*                                                                  */         
  12849.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  12850.  /*                                                                  */         
  12851.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  12852.  /* including the implied warranties of merchantability and fitness, */         
  12853.  /* are expressly denied.                                            */         
  12854.  /*                                                                  */         
  12855.  /* Provided this copyright notice is included, this software may    */         
  12856.  /* be freely distributed and not offered for sale.                  */         
  12857.  /*                                                                  */         
  12858.  /* Changes or modifications may be made and used only by the maker  */         
  12859.  /* of same, and not further distributed.  Such modifications should */         
  12860.  /* be mailed to the author for consideration for addition to the    */         
  12861.  /* software and incorporation in subsequent releases.               */         
  12862.  /*                                                                  */         
  12863.  /********************************************************************/         
  12864.                                                                                 
  12865. #pragma  csect(code,  "NN@DNNTP")                                               
  12866. #pragma  csect(static,"NN$DNNTP")                                               
  12867. #include "nn.h"                                                                 
  12868.                                                                                 
  12869. /****** Option ... process native NNTP protocol commands. ************/         
  12870.                                                                                 
  12871. void                                                                            
  12872. NNMdnntp(np,command)                                                            
  12873. Rstruc nncb *np;                                                                
  12874. char        *command;                                                           
  12875. {                                                                               
  12876.                                                                                 
  12877.  if (command && *command) {                                                     
  12878.    strncpy(np->nntp_command, command, CLIENT_BUF_MSGSIZE);                      
  12879.    NNMnntp(np);                    /* execute NNTP commands */                  
  12880.  }                                                                              
  12881.                                                                                 
  12882.  else while (NNMdispl(np,"NNM0    ") == 0 && !np->quit) {                       
  12883.                                                                                 
  12884.    (void)NNMivget(np,"NNCMD ",np->nntp_command,CLIENT_BUF_MSGSIZE);             
  12885.    if (np->ispfrc == 0) NNMnntp(np); /* execute NNTP commands */                
  12886.                                                                                 
  12887.    if (np->quit) break;                                                         
  12888.  }                                                                              
  12889.                                                                                 
  12890.  return;                                                                        
  12891. }                                                                               
  12892.                                                                                 
  12893. ./   ADD NAME=NNMDOIT,SSI=01120051                                              
  12894.                                                                                 
  12895.  /********************************************************************/         
  12896.  /*                                                                  */         
  12897.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  12898.  /*                                                                  */         
  12899.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  12900.  /* including the implied warranties of merchantability and fitness, */         
  12901.  /* are expressly denied.                                            */         
  12902.  /*                                                                  */         
  12903.  /* Provided this copyright notice is included, this software may    */         
  12904.  /* be freely distributed and not offered for sale.                  */         
  12905.  /*                                                                  */         
  12906.  /* Changes or modifications may be made and used only by the maker  */         
  12907.  /* of same, and not further distributed.  Such modifications should */         
  12908.  /* be mailed to the author for consideration for addition to the    */         
  12909.  /* software and incorporation in subsequent releases.               */         
  12910.  /*                                                                  */         
  12911.  /********************************************************************/         
  12912.                                                                                 
  12913. #pragma  csect(code,  "NN@DOIT ")                                               
  12914. #pragma  csect(static,"NN$DOIT ")                                               
  12915. #include "nn.h"                                                                 
  12916.                                                                                 
  12917. /****** Do it (whatever it is) to the article. ***********************/         
  12918.                                                                                 
  12919. void                                                                            
  12920. NNMdoit(np,ap,whatfor)                                                          
  12921. Rstruc nncb          *np;                                                       
  12922. Rstruc newsarticle   *ap;                                                       
  12923. Fool                  whatfor;                                                  
  12924. {                                                                               
  12925.  Rstruc newsgroup    *gp;                                                       
  12926.                                                                                 
  12927.  gp = np->current_newsgroup;                                                    
  12928.                                                                                 
  12929.  if (!gp) {                                                                     
  12930.    CRIT1("There is no current newsgroup.  This should not happen.");            
  12931.    return;                                                                      
  12932.  }                                                                              
  12933.                                                                                 
  12934.  switch (whatfor) {                                                             
  12935.    case 'S':                                                                    
  12936.             NNMvtx(np,gp,ap);                 /* View text */                   
  12937.             NNMmarr(np,gp,ap);                /* Make article read */           
  12938.             ap->action = READ;                                                  
  12939.             break;                                                              
  12940.    case 'E':                                                                    
  12941.             np->extract_write_error = FALSE;                                    
  12942.             np->extract_close_error = FALSE;                                    
  12943.             if (NNMxtx(np,ap,TRUE)) {         /* Extract text */                
  12944.               if (!np->extract_write_error &&                                   
  12945.                   !np->extract_close_error) {                                   
  12946.                 NNMmarr(np,gp,ap);            /* Make article read */           
  12947.                 ap->action = EXTRACTED;                                         
  12948.               }                                                                 
  12949.             }                                                                   
  12950.             break;                                                              
  12951.    case 'F':                                                                    
  12952.             NNMdpost(np,gp,ap);               /* Post followup */               
  12953.             ap->action = RETRIEVED;                                             
  12954.             break;                                                              
  12955.    case 'R':                                                                    
  12956.             NNMdmail(np,gp,ap);               /* Mail reply */                  
  12957.             ap->action = RETRIEVED;                                             
  12958.             break;                                                              
  12959.    case 'P':                                                                    
  12960.             NNMptx(np,ap);                    /* Print text */                  
  12961.             ap->action = PRINTED;                                               
  12962.             break;                                                              
  12963.    case 'C':                                                                    
  12964.             if (NNMdcan(np,gp,ap)) {          /* Cancel article */              
  12965.               ap->action = CANCELLED;                                           
  12966.             }                                                                   
  12967.             break;                                                              
  12968.  }                                                                              
  12969.                                                                                 
  12970.  np->top_article = ap;                                                          
  12971.                                                                                 
  12972.  return;                                                                        
  12973. }                                                                               
  12974.                                                                                 
  12975. ./   ADD NAME=NNMDPOST,SSI=01400041                                             
  12976.                                                                                 
  12977.  /********************************************************************/         
  12978.  /*                                                                  */         
  12979.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  12980.  /*                                                                  */         
  12981.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  12982.  /*                                                                  */         
  12983.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  12984.  /* including the implied warranties of merchantability and fitness, */         
  12985.  /* are expressly denied.                                            */         
  12986.  /*                                                                  */         
  12987.  /* Provided this copyright notice is included, this software may    */         
  12988.  /* be freely distributed and not offered for sale.                  */         
  12989.  /*                                                                  */         
  12990.  /* Changes or modifications may be made and used only by the maker  */         
  12991.  /* of same, and not further distributed.  Such modifications should */         
  12992.  /* be mailed to the author for consideration for addition to the    */         
  12993.  /* software and incorporation in subsequent releases.               */         
  12994.  /*                                                                  */         
  12995.  /********************************************************************/         
  12996.                                                                                 
  12997. #pragma  csect(code,  "NN@DPOST")                                               
  12998. #pragma  csect(static,"NN$DPOST")                                               
  12999. #include "nn.h"                                                                 
  13000.                                                                                 
  13001. #define NEWSGROUPS_LENGTH   256-sizeof("Newsgroups: ")                          
  13002. #define SUBJECT_LENGTH      256-sizeof("Subject: ")                             
  13003. #define PATH_LENGTH         256-sizeof("Path: ")                                
  13004. #define FROM_LENGTH         256-sizeof("From: ")                                
  13005. #define REPLY_TO_LENGTH     256-sizeof("Reply-to: ")                            
  13006. #define FOLLOWUP_TO_LENGTH  256-sizeof("Followup-to: ")                         
  13007.                                                                                 
  13008. #define HEADCAT(A,B)        strncat((A),(B),NEWSGROUPS_LENGTH)                  
  13009.                                                                                 
  13010. /****** Make a comma delimited list out of user's newsgroup spec. ****/         
  13011.                                                                                 
  13012. static void                                                                     
  13013. make_comma_delimited_list(instring,outstring)                                   
  13014. char                *instring;                                                  
  13015. char                *outstring;                                                 
  13016. {                                                                               
  13017.  char               *icp;                                                       
  13018.  char               *ocp;                                                       
  13019.  Bool                between;                                                   
  13020.                                                                                 
  13021.  between = FALSE;                                                               
  13022.  icp = instring + strspn(instring," ,");                                        
  13023.  ocp = outstring;                                                               
  13024.  do {                                                                           
  13025.    switch (*icp) {                                                              
  13026.      case '\0': *ocp = '\0'; break;                                             
  13027.      case ' ' :                                                                 
  13028.      case ',' :  between = TRUE; break;                                         
  13029.      default  :  if (between) {                                                 
  13030.                    between = FALSE;                                             
  13031.                    *(ocp++) = ',';                                              
  13032.                  }                                                              
  13033.                  *(ocp++) = tolower(*icp);                                      
  13034.                  break;                                                         
  13035.    }                                                                            
  13036.  } while (*icp++);                                                              
  13037.                                                                                 
  13038. }                                                                               
  13039.                                                                                 
  13040. /****** Collect additional article headers that we may need. *********/         
  13041.                                                                                 
  13042. static void                                                                     
  13043. get_more_headers(np,ap,newsgroups,followup_to)                                  
  13044. Rstruc nncb          *np;                                                       
  13045. Rstruc newsarticle   *ap;                                                       
  13046. char                 *newsgroups;                                               
  13047. char                 *followup_to;                                              
  13048. {                                                                               
  13049.  struct textline     *tp;                                                       
  13050.  struct texthdr      *thp;                                                      
  13051.  char                *cp;                                                       
  13052.  char                *newp;                                                     
  13053.  char                *colonp;                                                   
  13054.  int                  header_index;                                             
  13055.  char                 the_header[INTERNET_SIZE];                                
  13056.                                                                                 
  13057.  strcpy(newsgroups,  "");                                                       
  13058.  strcpy(followup_to, "");                                                       
  13059.                                                                                 
  13060.  if (!ap) return;                                                               
  13061.                                                                                 
  13062.  /* Grovel through headers looking for what we want.                            
  13063.   */                                                                            
  13064.                                                                                 
  13065.  newp = NULL;                                                                   
  13066.  thp = &ap->thdr;                                                               
  13067.  strcpy(the_header,"");                                                         
  13068.  for (tp=thp->first_text_line; tp; tp=tp->next) {                               
  13069.    if (tp->text[0] == '\0') break;                                              
  13070.    if (tp->text[0] == ' '                                                       
  13071.     || tp->text[0] == '\t') {                                                   
  13072.      cp = tp->text + strspn(tp->text," \t");                                    
  13073.      if (*cp == '\0') break;                                                    
  13074.    }                                                                            
  13075.    else {                                                                       
  13076.      header_index = 0;                                                          
  13077.      colonp = strchr(tp->text,':');                                             
  13078.      if (!colonp) break;                                                        
  13079.      strcpy(the_header,"");                                                     
  13080.      for (cp = tp->text;cp<colonp;cp++) {                                       
  13081.        the_header[header_index++] = toupper(*cp);                               
  13082.      }                                                                          
  13083.      the_header[header_index] = '\0';                                           
  13084.      cp = colonp+1 + strspn(colonp+1," \t");                                    
  13085.    }                                                                            
  13086.    if      (EQUAL(the_header,"NEWSGROUPS"  )) HEADCAT(newsgroups, cp);          
  13087.    else if (EQUAL(the_header,"FOLLOWUP-TO" )) HEADCAT(followup_to,cp);          
  13088.  }                                                                              
  13089.                                                                                 
  13090.  /* Lowercase and strip trailing whitespace. */                                 
  13091.                                                                                 
  13092.  for (cp = newsgroups;  *cp; cp++) *cp = tolower(*cp);                          
  13093.  for (; cp > newsgroups && isspace(*cp-1); cp--);                               
  13094.  *cp = '\0';                                                                    
  13095.                                                                                 
  13096.  for (cp = followup_to; *cp; cp++) *cp = tolower(*cp);                          
  13097.  for (; cp > followup_to && isspace(*cp-1); cp--);                              
  13098.  *cp = '\0';                                                                    
  13099.                                                                                 
  13100.  return;                                                                        
  13101.                                                                                 
  13102. }                                                                               
  13103.                                                                                 
  13104. /****** Post a news article. *****************************************/         
  13105.                                                                                 
  13106. void                                                                            
  13107. NNMdpost(np,gp,ap)                                                              
  13108. Rstruc nncb         *np;                                                        
  13109. Rstruc newsgroup    *gp;                                                        
  13110. Rstruc newsarticle  *ap;                                                        
  13111. {                                                                               
  13112.  Bool                filled       = FALSE;                                      
  13113.  Bool                edit_error   = FALSE;                                      
  13114.  Bool                post_error   = FALSE;                                      
  13115.  int                 l;                                                         
  13116.  int                 display_rc;                                                
  13117.  char               *postdefault  = NULL;                                       
  13118.  char               *lp;                                                        
  13119.  char               *cp;                                                        
  13120.  FILE               *efp          = NULL;                                       
  13121.  FILE               *sfp          = NULL;                                       
  13122.  struct tm          *nowtime;                                                   
  13123.  time_t              ltime;                                                     
  13124.  char                datestr[64];                                               
  13125.  char                midstr [64];                                               
  13126.  char                zuser   [9];                                               
  13127.  char                temp   [12];                                               
  13128.  char                tempdsn[L_tmpnam];                                         
  13129.  char                editstr[40+L_tmpnam];                                      
  13130.  char                edit_profile     [  9];                                    
  13131.  char                signature_file   [ 64];                                    
  13132.  char                post_message_id  [128];                                    
  13133.  char                zcmd             [ 81];                                    
  13134.  char                post_subject     [SUBJECT_LENGTH];                         
  13135.  char                post_path        [PATH_LENGTH];                            
  13136.  char                post_newsgroups  [NEWSGROUPS_LENGTH];                      
  13137.  char                post_followup_to [NEWSGROUPS_LENGTH];                      
  13138.  char                post_from        [FROM_LENGTH];                            
  13139.  char                nnpostng         [NEWSGROUPS_LENGTH];                      
  13140.  char                nnpostrt         [REPLY_TO_LENGTH];                        
  13141.  char                nnpostfo         [FOLLOWUP_TO_LENGTH];                     
  13142.  char                nnpostfr         [FROM_LENGTH];                            
  13143.  char                newsgroups       [NEWSGROUPS_LENGTH];                      
  13144.  char                followup_to      [NEWSGROUPS_LENGTH];                      
  13145.  char                postline         [260];                                    
  13146.  char                sigline          [260];                                    
  13147.                                                                                 
  13148.  (void)NNMivget(np,"ZUSER ",zuser,sizeof(zuser));                               
  13149.                                                                                 
  13150.  if (ap) {                                                                      
  13151.    if (strlen(ap->subject) >= 3 &&                                              
  13152.        (!memcmp(ap->subject,"Re:",3) ||                                         
  13153.         !memcmp(ap->subject,"re:",3) ||                                         
  13154.         !memcmp(ap->subject,"RE:",3)))   strcpy(post_subject,"");               
  13155.    else                                  strcpy(post_subject,"Re: ");           
  13156.    strncat(post_subject, ap->subject, sizeof(post_subject));                    
  13157.  }                                                                              
  13158.  else strcpy(post_subject,"");                                                  
  13159.                                                                                 
  13160.  sprintf(post_path,"%s!%s", np->client_hostname, zuser);                        
  13161.                                                                                 
  13162.  (void)NNMivput(np,"NNPOSTSJ ",post_subject,-1);                                
  13163.  if (ap) {                                                                      
  13164.    sprintf(temp,"%d",ap->number);                                               
  13165.    (void)NNMivput(np,"NNPOSTHA ",temp,        -1);                              
  13166.    (void)NNMivput(np,"NNPOSTHG ",gp->name,    -1);                              
  13167.  }                                                                              
  13168.  else {                                                                         
  13169.    (void)NNMivput(np,"NNPOSTHA ","",          -1);                              
  13170.    (void)NNMivput(np,"NNPOSTHG ",""          ,-1);                              
  13171.  }                                                                              
  13172.                                                                                 
  13173.  /*                                                                             
  13174.   * Simple-minded and wrong - newsgroups to post to = current one               
  13175.   *                                                                             
  13176.   * (void)NNMivput(np,"NNPOSTNG ",gp ? gp->name : "",-1);                       
  13177.   *                                                                             
  13178.   * The correct way:  if we are following up an article, then                   
  13179.   * if the Followup_to header is present, use that, else                        
  13180.   * use the Newsgroups: header.  If not there, use the newsgroup name.          
  13181.   *                                                                             
  13182.   * If fresh post, use the newsgroup name.                                      
  13183.   */                                                                            
  13184.                                                                                 
  13185.  if (gp) {                                                                      
  13186.    if (ap) {  /* this is a followup */                                          
  13187.      strcpy(newsgroups, "");                                                    
  13188.      strcpy(followup_to,"");                                                    
  13189.      get_more_headers(np,ap,newsgroups,followup_to);                            
  13190.      if      (EQUAL(followup_to,"poster")) {                                    
  13191.        ERR1(                                                                    
  13192. "Followups are directed to the poster.  Suggest you use REPLY instead."         
  13193.            );                                                                   
  13194.        postdefault = "";                                                        
  13195.      }                                                                          
  13196.      else if (strchr(followup_to,'@')) {                                        
  13197.        ERR1(                                                                    
  13198. "Followup header contains mailing address.  Suggest you REPLY instead."         
  13199.            );                                                                   
  13200.        postdefault = "";                                                        
  13201.      }                                                                          
  13202.      else if (*followup_to)  postdefault = followup_to;                         
  13203.      else if (*newsgroups)   postdefault = newsgroups;                          
  13204.      else                    postdefault = gp->name;                            
  13205.    }                                                                            
  13206.    else {     /* this is a fresh posting */                                     
  13207.      postdefault = gp->name;                                                    
  13208.    }                                                                            
  13209.  }                                                                              
  13210.  else {                                                                         
  13211.    postdefault = "";                                                            
  13212.  }                                                                              
  13213.                                                                                 
  13214.  (void)NNMivput(np,"NNPOSTNG ",postdefault,-1);                                 
  13215.                                                                                 
  13216.  /* Can't use this - C/370 compiler bug... */                                   
  13217.  /* strcpy(tempdsn,ap ? "" : np->maildsn); */                                   
  13218.                                                                                 
  13219.  if (ap) strcpy(tempdsn,"");                                                    
  13220.  else    strcpy(tempdsn,np->maildsn);                                           
  13221.                                                                                 
  13222.  if (!*tempdsn) {                                                               
  13223.    if (!tmpnam(tempdsn)) {                                                      
  13224.      ERR1(                                                                      
  13225. "A temporary data set name could not be created.  tmpnam() error."              
  13226.          );                                                                     
  13227.      return;                                                                    
  13228.    }                                                                            
  13229.    if (!(efp = OPEN_TEXT_FILE_FOR_WRITE(tempdsn))) {                            
  13230.      ERR2("Error trying to open temp data set: %s", tempdsn);                   
  13231.      return;                                                                    
  13232.    }                                                                            
  13233.    if (fclose(efp) < 0) {                                                       
  13234.      ERR2("Error trying to close temp data set: %s", tempdsn);                  
  13235.      return;                                                                    
  13236.    }                                                                            
  13237.    efp = NULL;                                                                  
  13238.    if (!ap) strcpy(np->maildsn,tempdsn);                                        
  13239.  }                                                                              
  13240.                                                                                 
  13241.  while (NNMdispl(np,"NNMQPOST") == 0) {                                         
  13242.                                                                                 
  13243.    NNMivget(np,"NNPOSTNG ",nnpostng,       sizeof(nnpostng));                   
  13244.    NNMivget(np,"NNPOSTRT ",nnpostrt,       sizeof(nnpostrt));                   
  13245.    NNMivget(np,"NNPOSTFO ",nnpostfo,       sizeof(nnpostfo));                   
  13246.    NNMivget(np,"NNPOSTFR ",nnpostfr,       sizeof(nnpostfr));                   
  13247.    NNMivget(np,"NNPOSTSJ ",post_subject,   sizeof(post_subject)   );            
  13248.    NNMivget(np,"NNPOSTSF ",signature_file, sizeof(signature_file) );            
  13249.    NNMivget(np,"NNEDPROF ",edit_profile,   sizeof(edit_profile)   );            
  13250.                                                                                 
  13251.    /* Create correctly formatted newsgroup listing. */                          
  13252.                                                                                 
  13253.    make_comma_delimited_list(nnpostng,post_newsgroups);                         
  13254.                                                                                 
  13255.    make_comma_delimited_list(nnpostfo,post_followup_to);                        
  13256.                                                                                 
  13257.    (void)NNMivput(np,"NNTEMPDS ",tempdsn,-1);                                   
  13258.                                                                                 
  13259.    /* Insure that we can access the signature file, if given. */                
  13260.                                                                                 
  13261.    if (*signature_file) {                                                       
  13262.      if (!(sfp=fopen(signature_file,"r"))) {                                    
  13263.        perror(signature_file);                                                  
  13264.        ERR2("Cannot open signature file %s.  Check that it is valid.",          
  13265.              signature_file);                                                   
  13266.        continue;                                                                
  13267.      }                                                                          
  13268.    }                                                                            
  13269.    else sfp = NULL;                                                             
  13270.                                                                                 
  13271.    /* Fill temporary data set with message to which we are replying,            
  13272.     * if this is a FOLLOWUP request,                                            
  13273.     * and the contents of the signature file if any.                            
  13274.     */                                                                          
  13275.                                                                                 
  13276.    if (!filled) {                                                               
  13277.      if (!(efp = OPEN_TEXT_FILE_FOR_WRITE(tempdsn))) {                          
  13278.        ERR2("Error trying to open temp data set: %s", tempdsn);                 
  13279.        continue;                                                                
  13280.      }                                                                          
  13281.      if (ap) {                                                                  
  13282.        np->extract_file            = efp;                                       
  13283.        np->extract_appending       = FALSE;                                     
  13284.        np->extract_separator_line  = FALSE;                                     
  13285.        np->extract_tab_expanding   = TRUE;                                      
  13286.        np->following_up            = TRUE;                                      
  13287.        fprintf(efp, "In article %s,\n%s writes:\n\n",                           
  13288.                     ap->message_id, ap->from);                                  
  13289.        (void)NNMxtx(np,ap,FALSE);            /* Extract article text */         
  13290.        np->following_up            = FALSE;                                     
  13291.        if (ferror(efp)) {                                                       
  13292.          ERR2("Error trying to write to temp data set: %s", tempdsn);           
  13293.          continue;                                                              
  13294.        }                                                                        
  13295.      }                                                                          
  13296.      if (sfp) {                                                                 
  13297.        fprintf(efp,"\n--\n",efp);                                               
  13298.        if (ferror(efp)) np->extract_write_error = TRUE;                         
  13299.        for (;;) {                                                               
  13300.          fgets(sigline,sizeof(sigline),sfp);                                    
  13301.          if (ferror(sfp)) {                                                     
  13302.            ERR2(                                                                
  13303.   "Cannot read from signature file %s.  Check that it is valid.",               
  13304.                 signature_file);                                                
  13305.            break;                                                               
  13306.          }                                                                      
  13307.          if (feof(sfp)) break;                                                  
  13308.          if ((cp=strchr(sigline,'\n'))) *cp = '\0';                             
  13309.          l = strlen(sigline);                                                   
  13310.          fwrite(sigline,(l>251 ? 251 : l),1,efp);                               
  13311.          if (ferror(efp)) {                                                     
  13312.            np->extract_write_error = TRUE; break;                               
  13313.          }                                                                      
  13314.          if (fputc('\n',efp) == EOF) {                                          
  13315.            np->extract_write_error = TRUE; break;                               
  13316.          }                                                                      
  13317.        }                                                                        
  13318.        (void)fclose(sfp);                                                       
  13319.        if (ferror(efp)) {                                                       
  13320.          ERR2("Error trying to write to temp data set: %s", tempdsn);           
  13321.          continue;                                                              
  13322.        }                                                                        
  13323.      }                                                                          
  13324.      if (fclose(efp) < 0) {                                                     
  13325.        ERR2("Error trying to close temp data set: %s", tempdsn);                
  13326.        continue;                                                                
  13327.      }                                                                          
  13328.      filled = TRUE;                                                             
  13329.    }                                                                            
  13330.                                                                                 
  13331.    efp = NULL;                                                                  
  13332.                                                                                 
  13333. #ifndef I370                                                                    
  13334.    sprintf(editstr,"EDIT DATASET(%s) PROFILE(%s)",tempdsn,edit_profile);        
  13335. #else                                                                           
  13336.    sprintf(editstr, "EDIT DATASET('%s') PROFILE(%s)",                           
  13337.            tempdsn+4, edit_profile);                                            
  13338. #endif                                                                          
  13339.                                                                                 
  13340.    edit_error = FALSE;                                                          
  13341.                                                                                 
  13342.    (void)NNMispf(np,editstr);                                                   
  13343.    switch (np->ispfrc) {                                                        
  13344.      case 0:  edit_error = FALSE;      break;                                   
  13345.      case 4:  ERR1(                                                             
  13346. "Edit ended without SAVE, posting cancelled.  Reenter and SAVE to post."        
  13347.                   );                         continue;                          
  13348.      default: edit_error = TRUE;       break;                                   
  13349.    }                                                                            
  13350.                                                                                 
  13351.    if (edit_error) continue;                                                    
  13352.                                                                                 
  13353.    /* Confirm posting. */                                                       
  13354.                                                                                 
  13355.    (void)NNMispf (np,"ADDPOP ");                                                
  13356.    display_rc = NNMdispl(np,"NNMPCONP");                                        
  13357.    (void)NNMispf (np,"REMPOP ");                                                
  13358.    (void)NNMivget(np,"ZCMD ",zcmd,sizeof(zcmd));                                
  13359.    if (display_rc > 0) continue;                                                
  13360.    if (*zcmd == 'c' || *zcmd == 'C') {                                          
  13361.      (void)NNMivput(np,"ZCMD ","",-1);                                          
  13362.      ERR1("Posting cancelled by user.  Reenter EDIT and SAVE to post.");        
  13363.      return;                                                                    
  13364.    }                                                                            
  13365.                                                                                 
  13366.    if (!(efp = fopen(tempdsn,"r"))) {                                           
  13367.      ERR2("Error trying to open temp data set: %s", tempdsn);                   
  13368.      continue;                                                                  
  13369.    }                                                                            
  13370.                                                                                 
  13371.    /* Start posting here.                                                       
  13372.     *                                                                           
  13373.     * Me:     POST                                                              
  13374.     * Server: 340 send article to be posted.  End with <CR-LF>.<CR-LF>          
  13375.     *     or: 440 posting not allowed                                           
  13376.     * If 430...                                                                 
  13377.     *                                                                           
  13378.     * See RFC850 for details.                                                   
  13379.     *                                                                           
  13380.     * Me:     required_header: xxx                                              
  13381.     * ...                                                                       
  13382.     * Me:     <null line>                                                       
  13383.     * Read text from tempdsn                                                    
  13384.     * Me:     <text with leading periods hacked>                                
  13385.     * Me:     .                                                                 
  13386.     * Server: 240 article posted OK                                             
  13387.     *     or: 441 posting failed                                                
  13388.     */                                                                          
  13389.                                                                                 
  13390.     /* See RFC 1036 for full information. */                                    
  13391.                                                                                 
  13392.    /* Required headers - from, date, subject, newsgroups,                       
  13393.     *                    message-id, path                                       
  13394.     */                                                                          
  13395.                                                                                 
  13396.    /* Optional headers - reply-to, sender, followup-to, expires, xref,          
  13397.     *                    references, control, distribution, lines,              
  13398.     *                    organization, keywords, summary, approved              
  13399.     */                                                                          
  13400.                                                                                 
  13401.                                                                                 
  13402.    /* Get current date and time, and generate a message id from it.             
  13403.     * If the message id is a duplicate, loop around until it isn't.             
  13404.     */                                                                          
  13405.                                                                                 
  13406.    do {                                                                         
  13407.                                                                                 
  13408.      time(<ime);                                                              
  13409.      nowtime = localtime(<ime);                                               
  13410.      strftime(datestr,sizeof(datestr)-1,                                        
  13411.                       "%a, %d %b %Y %H:%M %Z",nowtime);                         
  13412.      strftime(midstr, sizeof(midstr)-1,                                         
  13413.                       "%Y%m%d%H%M%S",nowtime);                                  
  13414.                                                                                 
  13415.      sprintf(post_message_id,"<%s%s@%s>",                                       
  13416.                              midstr, zuser, np->client_hostname);               
  13417.                                                                                 
  13418.    } while (strcmp(post_message_id,np->messageid) == 0);                        
  13419.                                                                                 
  13420.    strcpy(np->messageid,post_message_id);                                       
  13421.                                                                                 
  13422.    do {                                                                         
  13423.      strcpy(np->nntp_command,"POST");                                           
  13424.      if (!NNMsockt(np))     break;  /* Send socket command to server */         
  13425.      if (!NNMgsrvl(np,&lp)) break;  /* Get server line */                       
  13426.      switch (np->nntp_message_num) {                                            
  13427.        case 340: post_error = FALSE;                                            
  13428.                  break;                                                         
  13429.        case 440: ERR2(                                                          
  13430.          "Posting not allowed.  Server %s did not accept the post.",            
  13431.                       np->nnserver);                                            
  13432.                  post_error = TRUE;                                             
  13433.                  break;                                                         
  13434.        default:  NNMrperr(np);       /* Report protocol error */                
  13435.                  post_error = TRUE;                                             
  13436.                  break;                                                         
  13437.      }                                                                          
  13438.                                                                                 
  13439.      if (post_error) break;                                                     
  13440.                                                                                 
  13441.      /* Assert np->server_finished_replying == TRUE                             
  13442.       *     && np->receiving_text == TRUE                                       
  13443.       */                                                                        
  13444.                                                                                 
  13445.      if (*nnpostfr)                                                             
  13446.           sprintf(post_from,"%s@%s (%s)",                                       
  13447.                             zuser, np->client_hostname, nnpostfr);              
  13448.      else sprintf(post_from,"%s@%s",                                            
  13449.                             zuser, np->client_hostname);                        
  13450.                                                                                 
  13451.      sprintf(np->nntp_command,"Path: %s", post_path);                           
  13452.      if (!NNMsockt(np)) break;   /* Send socket command to server */            
  13453.                                                                                 
  13454.      sprintf(np->nntp_command,"Newsgroups: %s",post_newsgroups);                
  13455.      if (!NNMsockt(np)) break;   /* Send socket command to server */            
  13456.                                                                                 
  13457.      sprintf(np->nntp_command,"Subject: %s",post_subject);                      
  13458.      if (!NNMsockt(np)) break;   /* Send socket command to server */            
  13459.                                                                                 
  13460.      sprintf(np->nntp_command,"Message-ID: %s", post_message_id);               
  13461.      if (!NNMsockt(np)) break;   /* Send socket command to server */            
  13462.                                                                                 
  13463.      sprintf(np->nntp_command,"From: %s", post_from);                           
  13464.      if (!NNMsockt(np)) break;   /* Send socket command to server */            
  13465.                                                                                 
  13466.      sprintf(np->nntp_command,"Date: %s", datestr);                             
  13467.      if (!NNMsockt(np)) break;   /* Send socket command to server */            
  13468.                                                                                 
  13469.      /* insert optional headers here if we ever have any */                     
  13470.                                                                                 
  13471.      sprintf(np->nntp_command,"Sender: MVS NNTP News Reader <%s@%s>",           
  13472.                               NNMVS_NAME, np->client_hostname);                 
  13473.      if (!NNMsockt(np)) break;   /* Send socket command to server */            
  13474.                                                                                 
  13475.      if (ap) {                                                                  
  13476.     /*                                                                          
  13477.      * Uncomment this section when a references field in the                    
  13478.      * newsarticle struct is added.  Will require total recompilation           
  13479.      *                                                                          
  13480.      * if (ap->references)                                                      
  13481.      *  sprintf(np->nntp_command,"References: %s %s",                           
  13482.      *          ap->references, ap->message_id);                                
  13483.      * else                                                                     
  13484.      */                                                                         
  13485.         sprintf(np->nntp_command,"References: %s",ap->message_id);              
  13486.        if (!NNMsockt(np)) break;   /* Send socket command to server */          
  13487.      }                                                                          
  13488.                                                                                 
  13489.      /* optional headers */                                                     
  13490.                                                                                 
  13491.      if (*nnpostrt) {                                                           
  13492.        sprintf(np->nntp_command,"Reply-to: %s", nnpostrt);                      
  13493.        if (!NNMsockt(np)) break;   /* Send socket command to server */          
  13494.      }                                                                          
  13495.      if (*post_followup_to) {                                                   
  13496.        sprintf(np->nntp_command,"Followup-to: %s", post_followup_to);           
  13497.        if (!NNMsockt(np)) break;   /* Send socket command to server */          
  13498.      }                                                                          
  13499.                                                                                 
  13500.      strcpy(np->nntp_command,"");                                               
  13501.      if (!NNMsockt(np)) break;   /* Send socket command to server */            
  13502.                                                                                 
  13503.      while (!feof(efp) && !ferror(efp)) {                                       
  13504.        fgets(postline,sizeof(postline),efp);                                    
  13505.        if (feof(efp)) break;                                                    
  13506.        if (ferror(efp)) break;                                                  
  13507.        if (*postline && postline[l=strlen(postline)-1] == '\n')                 
  13508.           postline[l] = '\0';                                                   
  13509.        if (postline[0] == '.') strcpy(np->nntp_command,".");                    
  13510.        else                    strcpy(np->nntp_command,"");                     
  13511.        strcat(np->nntp_command,postline);                                       
  13512.        if (!NNMsockt(np)) break;   /* Send socket command to server */          
  13513.      }                                                                          
  13514.                                                                                 
  13515.      strcpy(np->nntp_command,".");                                              
  13516.      if (!NNMsockt(np)) break;   /* Send socket command to server */            
  13517.                                                                                 
  13518.      if (!NNMgsrvl(np,&lp)) break;  /* Get server line */                       
  13519.      switch (np->nntp_message_num) {                                            
  13520.        case 240: post_error = FALSE;                                            
  13521.                  break;                                                         
  13522.        case 441: NNMclrtx(np,NULL);               /* Clear text */              
  13523.                  NNMouttx(np,np->server_buf,NULL);/* Output text line */        
  13524.                  NNMvtx(np,NULL,NULL);            /* View text */               
  13525.  ERR2("Posting failed.  Server %s rejected the post.",np->nnserver);            
  13526.                  post_error = TRUE;                                             
  13527.                  break;                                                         
  13528.        default:  NNMrperr(np);       /* Report protocol error */                
  13529.                  post_error = TRUE;                                             
  13530.                  break;                                                         
  13531.      }                                                                          
  13532.                                                                                 
  13533.      NNMesrvr(np);                   /* End server read */                      
  13534.                                                                                 
  13535.      break;                                                                     
  13536.                                                                                 
  13537.    } while(FALSE); /* one-time DO so I can break out of it */                   
  13538.                                                                                 
  13539.    if (!post_error) {                                                           
  13540.      (void)NNMivput(np,"NNPOSTID ",post_message_id,-1);                         
  13541.      WARN2("Your article has been posted.  Message ID: %s",                     
  13542.            post_message_id);                                                    
  13543.      break;                                                                     
  13544.    }                                                                            
  13545.                                                                                 
  13546.  }                                                                              
  13547.                                                                                 
  13548.  if (!efp) return;                                                              
  13549.                                                                                 
  13550.  if (ferror(efp)) {                                                             
  13551.    ERR2("Error trying to read from temp data set: %s", tempdsn);                
  13552.  }                                                                              
  13553.                                                                                 
  13554.  if (fclose(efp) < 0) {                                                         
  13555.    ERR2("Error trying to close temp data set: %s", tempdsn);                    
  13556.  }                                                                              
  13557.                                                                                 
  13558.  if (ap) {                                                                      
  13559.    if (remove(tempdsn) < 0) {                                                   
  13560.      ERR2("Error trying to delete temp data set: %s", tempdsn);                 
  13561.    }                                                                            
  13562.  }                                                                              
  13563.                                                                                 
  13564.  return;                                                                        
  13565. }                                                                               
  13566.                                                                                 
  13567. ./   ADD NAME=NNMDSOPT,SSI=010F0056                                             
  13568.                                                                                 
  13569.  /********************************************************************/         
  13570.  /*                                                                  */         
  13571.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  13572.  /*                                                                  */         
  13573.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  13574.  /* including the implied warranties of merchantability and fitness, */         
  13575.  /* are expressly denied.                                            */         
  13576.  /*                                                                  */         
  13577.  /* Provided this copyright notice is included, this software may    */         
  13578.  /* be freely distributed and not offered for sale.                  */         
  13579.  /*                                                                  */         
  13580.  /* Changes or modifications may be made and used only by the maker  */         
  13581.  /* of same, and not further distributed.  Such modifications should */         
  13582.  /* be mailed to the author for consideration for addition to the    */         
  13583.  /* software and incorporation in subsequent releases.               */         
  13584.  /*                                                                  */         
  13585.  /********************************************************************/         
  13586.                                                                                 
  13587. #pragma  csect(code,  "NN@DSOPT")                                               
  13588. #pragma  csect(static,"NN$DSOPT")                                               
  13589. #include "nn.h"                                                                 
  13590.                                                                                 
  13591. /****** Set options. *************************************************/         
  13592.                                                                                 
  13593. static void                                                                     
  13594. set_options(np,panelname,which)                                                 
  13595. Rstruc nncb       *np;                                                          
  13596. char              *panelname;                                                   
  13597. enum user_option   which;                                                       
  13598. {                                                                               
  13599.                                                                                 
  13600.  while (NNMdispl(np,panelname) == 0) {                                          
  13601.    NNMsopt(np,which);               /* Actually set options */                  
  13602.  }                                                                              
  13603.                                                                                 
  13604.  return;                                                                        
  13605. }                                                                               
  13606.                                                                                 
  13607. /****** Option ... set NNMVS default processing options. *************/         
  13608.                                                                                 
  13609. void                                                                            
  13610. NNMdsopt(np,option)                                                             
  13611. Rstruc nncb *np;                                                                
  13612. char        *option;                                                            
  13613. {                                                                               
  13614.  int         displayrc;                                                         
  13615.  Bool        asked_for;                                                         
  13616.  Bool        force_choice;                                                      
  13617.  char        nnchoice[9];                                                       
  13618.                                                                                 
  13619.  force_choice = FALSE;                                                          
  13620.                                                                                 
  13621.  do {                                                                           
  13622.                                                                                 
  13623.    asked_for = TRUE;                                                            
  13624.                                                                                 
  13625.    if (!force_choice && option && *option) {                                    
  13626.      strncpy(nnchoice,option,sizeof(nnchoice)-1);                               
  13627.                                                                                 
  13628.    }                                                                            
  13629.    else {                                                                       
  13630.                                                                                 
  13631.      (void)NNMispf(np,"ADDPOP");                                                
  13632.      if (NNMdispl(np,"NNMPOPT ") > 0) {                                         
  13633.        asked_for = FALSE;                                                       
  13634.      }                                                                          
  13635.      else {                                                                     
  13636.        (void)NNMivget(np,"NNCHOICE ",nnchoice,sizeof(nnchoice));                
  13637.        if (*nnchoice == '?') {                                                  
  13638.          ERR1("Invalid choice;\                                                 
  13639. Move the cursor to a selection (or type S next to it) and press ENTER."         
  13640.              );                                                                 
  13641.        }                                                                        
  13642.      }                                                                          
  13643.                                                                                 
  13644.      (void)NNMispf(np,"REMPOP");                                                
  13645.    }                                                                            
  13646.                                                                                 
  13647.    if (asked_for) {                                                             
  13648.                                                                                 
  13649.      if      (EQUAL(nnchoice,"1")) {                                            
  13650.        set_options(np,"NNMRFCH ",OPTION_HEADER);                                
  13651.        break;                                                                   
  13652.      }                                                                          
  13653.      else if (EQUAL(nnchoice,"2")) {                                            
  13654.        set_options(np,"NNMOPTS ",OPTION_OTHER);                                 
  13655.        break;                                                                   
  13656.      }                                                                          
  13657.      else if (EQUAL(nnchoice,"3")) {                                            
  13658.        set_options(np,"NNMOPTT ",OPTION_VIEW);                                  
  13659.        break;                                                                   
  13660.      }                                                                          
  13661.      else {                                                                     
  13662.        ERR1("Invalid choice;\                                                   
  13663. Move the cursor to a selection (or type S next to it) and press ENTER."         
  13664.            );                                                                   
  13665.        force_choice = TRUE;                                                     
  13666.        continue;                                                                
  13667.      }                                                                          
  13668.    }                                                                            
  13669.                                                                                 
  13670.  } while (asked_for);                                                           
  13671.                                                                                 
  13672.  return;                                                                        
  13673.                                                                                 
  13674. }                                                                               
  13675.                                                                                 
  13676. ./   ADD NAME=NNMDUMP,SSI=01030030                                              
  13677.                                                                                 
  13678.  /********************************************************************/         
  13679.  /*                                                                  */         
  13680.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  13681.  /*                                                                  */         
  13682.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  13683.  /* including the implied warranties of merchantability and fitness, */         
  13684.  /* are expressly denied.                                            */         
  13685.  /*                                                                  */         
  13686.  /* Provided this copyright notice is included, this software may    */         
  13687.  /* be freely distributed and not offered for sale.                  */         
  13688.  /*                                                                  */         
  13689.  /* Changes or modifications may be made and used only by the maker  */         
  13690.  /* of same, and not further distributed.  Such modifications should */         
  13691.  /* be mailed to the author for consideration for addition to the    */         
  13692.  /* software and incorporation in subsequent releases.               */         
  13693.  /*                                                                  */         
  13694.  /********************************************************************/         
  13695.                                                                                 
  13696. #pragma  csect(code,  "NN@DUMP ")                                               
  13697. #pragma  csect(static,"NN$DUMP ")                                               
  13698. #include "nn.h"                                                                 
  13699.                                                                                 
  13700. /****** Dump some data. **********************************************/         
  13701.                                                                                 
  13702. void                                                                            
  13703. NNMdump(struct nncb *np, char *label, char *p,int r)                            
  13704. {                                                                               
  13705.  int i;                                                                         
  13706.                                                                                 
  13707.  if (!np->debug_file) return;                                                   
  13708.                                                                                 
  13709.  if (r == -2) {                                                                 
  13710.    fprintf(np->debug_file,"%s:  %d\n",label,(int)p);                            
  13711.    return;                                                                      
  13712.  }                                                                              
  13713.                                                                                 
  13714.  if (r == -1) r = strlen(p);                                                    
  13715.                                                                                 
  13716.  fprintf(np->debug_file,"%s:   (%d characters)\n",label,r);                     
  13717.  for (i=0;i<77;i++) fprintf(np->debug_file,"-");                                
  13718.  fprintf(np->debug_file,"\n");                                                  
  13719.  for (i=0;i<r;i++) {                                                            
  13720.    char c = *(p+i);                                                             
  13721.    if (isprint(c))  fprintf(np->debug_file,"%c",c);                             
  13722.    else             fprintf(np->debug_file,"<0x%2.2x>",c);                      
  13723.  }                                                                              
  13724.  fprintf(np->debug_file,"\n");                                                  
  13725.  for (i=0;i<77;i++) fprintf(np->debug_file,"-");                                
  13726.  fprintf(np->debug_file,"\n");                                                  
  13727.                                                                                 
  13728.  return;                                                                        
  13729.                                                                                 
  13730. }                                                                               
  13731.                                                                                 
  13732. ./   ADD NAME=NNMESRVR,SSI=01050027                                             
  13733.                                                                                 
  13734.  /********************************************************************/         
  13735.  /*                                                                  */         
  13736.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  13737.  /*                                                                  */         
  13738.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  13739.  /* including the implied warranties of merchantability and fitness, */         
  13740.  /* are expressly denied.                                            */         
  13741.  /*                                                                  */         
  13742.  /* Provided this copyright notice is included, this software may    */         
  13743.  /* be freely distributed and not offered for sale.                  */         
  13744.  /*                                                                  */         
  13745.  /* Changes or modifications may be made and used only by the maker  */         
  13746.  /* of same, and not further distributed.  Such modifications should */         
  13747.  /* be mailed to the author for consideration for addition to the    */         
  13748.  /* software and incorporation in subsequent releases.               */         
  13749.  /*                                                                  */         
  13750.  /********************************************************************/         
  13751.                                                                                 
  13752. #pragma  csect(code,  "NN@ESRVR")                                               
  13753. #pragma  csect(static,"NN$ESRVR")                                               
  13754. #include "nn.h"                                                                 
  13755.                                                                                 
  13756. /****** End server read. *********************************************/         
  13757.                                                                                 
  13758. void                                                                            
  13759. NNMesrvr(np)                                                                    
  13760. Rstruc nncb  *np;                                                               
  13761. {                                                                               
  13762.  char       *lp;                                                                
  13763.  Bool        found_more_server_data = FALSE;                                    
  13764.                                                                                 
  13765.  NNMclrtx(np,NULL);                    /* Clear text */                         
  13766.                                                                                 
  13767.  do {                                                                           
  13768.                                                                                 
  13769.    if (NNMgsrvl(np,&lp)) {             /* Get server line */                    
  13770.      if (lp) {                                                                  
  13771.        found_more_server_data = TRUE;                                           
  13772.        (void)NNMouttx(np,lp,NULL);     /* Output text line */                   
  13773.      }                                                                          
  13774.    }                                                                            
  13775.                                                                                 
  13776.  } while (lp);                                                                  
  13777.                                                                                 
  13778.  if (found_more_server_data) {                                                  
  13779.    ERR1(                                                                        
  13780. "More data was returned by the news server than the client expected."           
  13781.        );                                                                       
  13782.    NNMvtx(np,NULL,NULL);               /* View text */                          
  13783.  }                                                                              
  13784.                                                                                 
  13785.  return;                                                                        
  13786. }                                                                               
  13787.                                                                                 
  13788. ./   ADD NAME=NNMESTNG,SSI=01050016                                             
  13789.                                                                                 
  13790.  /********************************************************************/         
  13791.  /*                                                                  */         
  13792.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  13793.  /*                                                                  */         
  13794.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  13795.  /* including the implied warranties of merchantability and fitness, */         
  13796.  /* are expressly denied.                                            */         
  13797.  /*                                                                  */         
  13798.  /* Provided this copyright notice is included, this software may    */         
  13799.  /* be freely distributed and not offered for sale.                  */         
  13800.  /*                                                                  */         
  13801.  /* Changes or modifications may be made and used only by the maker  */         
  13802.  /* of same, and not further distributed.  Such modifications should */         
  13803.  /* be mailed to the author for consideration for addition to the    */         
  13804.  /* software and incorporation in subsequent releases.               */         
  13805.  /*                                                                  */         
  13806.  /********************************************************************/         
  13807.                                                                                 
  13808. #pragma  csect(code,  "NN@ESTNG")                                               
  13809. #pragma  csect(static,"NN$ESTNG")                                               
  13810. #include "nn.h"                                                                 
  13811.                                                                                 
  13812. /****** Establish newsgroup. *****************************************/         
  13813.                                                                                 
  13814. Bool                                                                            
  13815. NNMestng(np,group)                                                              
  13816. Rstruc nncb        *np;                                                         
  13817. char               *group;                                                      
  13818. {                                                                               
  13819.  char              *lp;                                                         
  13820.  Bool               null_group_passed = FALSE;                                  
  13821.                                                                                 
  13822.  /* A null group means reissue the server command to select the                 
  13823.     current newsgroup if it is necessary. */                                    
  13824.                                                                                 
  13825.  if (group == NULL) {                                                           
  13826.    null_group_passed = TRUE;                                                    
  13827.    if (np->current_newsgroup == NULL) {                                         
  13828.      fprintf(stderr,"NNMestng: no current newsgroup\n");                        
  13829.      return FALSE;                                                              
  13830.    }                                                                            
  13831.    if (np->newsgroup_selected) return TRUE;                                     
  13832.    group = np->current_newsgroup->name;                                         
  13833.  }                                                                              
  13834.                                                                                 
  13835.  np->newsgroup_not_found = FALSE;                                               
  13836.                                                                                 
  13837.  /* Send "GROUP xxxx" to news server. */                                        
  13838.                                                                                 
  13839.  strcpy(np->nntp_command,"GROUP ");                                             
  13840.  strcat(np->nntp_command,group);                                                
  13841.  if (!NNMsockt(np)) return FALSE;    /* Send socket command to server */        
  13842.                                                                                 
  13843.    /* Receive response.  Should be one of:                                      
  13844.     *   211 n f l s group selected                                              
  13845.     *   411 no such news group                                                  
  13846.     */                                                                          
  13847.                                                                                 
  13848.  if (!NNMgsrvl(np,&lp)) return FALSE;  /* Get server line */                    
  13849.  switch (np->nntp_message_num) {                                                
  13850.    case 211:                           /* n f l s group selected */             
  13851.              break;                                                             
  13852.    case 411:                               /* no such news group */             
  13853.              fprintf(stderr,"%s: no such newsgroup\n",group);                   
  13854.              ERR3("No such newsgroup.  %s is unknown to server %s.",            
  13855.                   group, np->nnserver);                                         
  13856.              np->newsgroup_not_found = TRUE;                                    
  13857.              return FALSE;                                                      
  13858.    default:                                                                     
  13859.              NNMrperr(np);        /* Report protocol error */                   
  13860.              return FALSE;                                                      
  13861.  }                                                                              
  13862.                                                                                 
  13863.  np->newsgroup_selected = TRUE;                                                 
  13864.                                                                                 
  13865.  return TRUE;                                                                   
  13866.                                                                                 
  13867. }                                                                               
  13868.                                                                                 
  13869. ./   ADD NAME=NNMFREEM,SSI=01020018                                             
  13870.                                                                                 
  13871.  /********************************************************************/         
  13872.  /*                                                                  */         
  13873.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  13874.  /*                                                                  */         
  13875.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  13876.  /* including the implied warranties of merchantability and fitness, */         
  13877.  /* are expressly denied.                                            */         
  13878.  /*                                                                  */         
  13879.  /* Provided this copyright notice is included, this software may    */         
  13880.  /* be freely distributed and not offered for sale.                  */         
  13881.  /*                                                                  */         
  13882.  /* Changes or modifications may be made and used only by the maker  */         
  13883.  /* of same, and not further distributed.  Such modifications should */         
  13884.  /* be mailed to the author for consideration for addition to the    */         
  13885.  /* software and incorporation in subsequent releases.               */         
  13886.  /*                                                                  */         
  13887.  /********************************************************************/         
  13888.                                                                                 
  13889. #pragma  csect(code,  "NN@FREEM")                                               
  13890. #pragma  csect(static,"NN$FREEM")                                               
  13891. #include "nn.h"                                                                 
  13892.                                                                                 
  13893. /****** Free memory. *************************************************/         
  13894.                                                                                 
  13895. void                                                                            
  13896. NNMfreem(np,stuff,whatfor)                                                      
  13897. Rstruc nncb    *np;                                                             
  13898. char           *stuff;                                                          
  13899. char           *whatfor;                                                        
  13900. {                                                                               
  13901.                                                                                 
  13902.  free(stuff);                                                                   
  13903.                                                                                 
  13904.  if (np->debug_file) {                                                          
  13905.    fprintf(np->debug_file,"freemem: freed memory for %s\n", whatfor);           
  13906.  }                                                                              
  13907.  return;                                                                        
  13908.                                                                                 
  13909. }                                                                               
  13910.                                                                                 
  13911. ./   ADD NAME=NNMGETDS,SSI=01150008                                             
  13912.                                                                                 
  13913.  /********************************************************************/         
  13914.  /*                                                                  */         
  13915.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  13916.  /*                                                                  */         
  13917.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  13918.  /*                                                                  */         
  13919.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  13920.  /* including the implied warranties of merchantability and fitness, */         
  13921.  /* are expressly denied.                                            */         
  13922.  /*                                                                  */         
  13923.  /* Provided this copyright notice is included, this software may    */         
  13924.  /* be freely distributed and not offered for sale.                  */         
  13925.  /*                                                                  */         
  13926.  /* Changes or modifications may be made and used only by the maker  */         
  13927.  /* of same, and not further distributed.  Such modifications should */         
  13928.  /* be mailed to the author for consideration for addition to the    */         
  13929.  /* software and incorporation in subsequent releases.               */         
  13930.  /*                                                                  */         
  13931.  /********************************************************************/         
  13932.                                                                                 
  13933. #pragma  csect(code,  "NN@GETDS")                                               
  13934. #pragma  csect(static,"NN$GETDS")                                               
  13935. #include "nn.h"                                                                 
  13936.                                                                                 
  13937. #define DUMMY_FILE_POINTER_FOR_PDS  (FILE *)(-1)                                
  13938.                                                                                 
  13939. /****** Prompt user for the name of a data set to extract into. ******/         
  13940.                                                                                 
  13941. FILE *                                                                          
  13942. NNMgetds(np,ep)                                                                 
  13943. Rstruc nncb         *np;                                                        
  13944. Rstruc extraction   *ep;                                                        
  13945. {                                                                               
  13946.  FILE               *xfp;                                                       
  13947.  Bool                asked_for;                                                 
  13948.  char                nnexdsn[65];    /* data set name for extraction */         
  13949.  char                nnexapp [4];    /* YES or NO for append mode    */         
  13950.  char                nnextab [4];    /* YES or NO for tab expansion  */         
  13951.  char                nnexblk [4];    /* YES or NO for blank after sep*/         
  13952.  char                nnexsep[81];    /* Separator line (optional)    */         
  13953.  char                nnexan1[16];    /* From article number          */         
  13954.  char                nnexan2[16];    /* To   article number          */         
  13955.  char                nnexpmp [9];    /* PDS member name prefix       */         
  13956.  char                ddname  [9];                                               
  13957.  char                member  [9];                                               
  13958.  char                pdspec [32];                                               
  13959.  char                quoted_dsname [67];                                        
  13960.  char                formatted_number [11];                                     
  13961.                                                                                 
  13962.  /* Display panel asking for data set name into which to extract. */            
  13963.                                                                                 
  13964.  xfp = NULL;                                                                    
  13965.  asked_for = TRUE;                                                              
  13966.                                                                                 
  13967.  (void)NNMispf(np,"ADDPOP");                                                    
  13968.                                                                                 
  13969.  while (xfp == NULL) {                                                          
  13970.                                                                                 
  13971.    /* Keep asking for a dsname until one works or END pressed. */               
  13972.                                                                                 
  13973.    if (NNMdispl(np,ep->panelname) > 0) {                                        
  13974.      asked_for = FALSE;                                                         
  13975.      xfp = NULL;                                                                
  13976.      break;                                                                     
  13977.    }                                                                            
  13978.                                                                                 
  13979.    (void)NNMivget(np,"NNEXDSN ",nnexdsn,sizeof(nnexdsn));                       
  13980.    (void)NNMivget(np,"NNEXTAB ",nnextab,sizeof(nnextab));                       
  13981.    (void)NNMivget(np,"NNEXAN1 ",nnexan1,sizeof(nnexan1));                       
  13982.    (void)NNMivget(np,"NNEXAN2 ",nnexan2,sizeof(nnexan2));                       
  13983.    if (ep->mode == PDS) {                                                       
  13984.      (void)NNMivget(np,"NNEXPMP ",nnexpmp,sizeof(nnexpmp));                     
  13985.    }                                                                            
  13986.    else {                                                                       
  13987.      (void)NNMivget(np,"NNEXAPP ",nnexapp,sizeof(nnexapp));                     
  13988.      (void)NNMivget(np,"NNEXBLK ",nnexblk,sizeof(nnexblk));                     
  13989.      (void)NNMivget(np,"NNEXSEP ",nnexsep,sizeof(nnexsep));                     
  13990.    }                                                                            
  13991.                                                                                 
  13992.    if (ep->mode == PDS) {                                                       
  13993.                                                                                 
  13994.      ep->appending = FALSE;                                                     
  13995.      ep->blanking  = FALSE;                                                     
  13996.      strcpy(ep->separator,"");                                                  
  13997.      strcpy(ep->ddname,"");                                                     
  13998.      strcpy(ep->member_prefix,nnexpmp);                                         
  13999.                                                                                 
  14000.      /* Note: panel forces fully-qualified name to pass to allocate */          
  14001.                                                                                 
  14002.      /* check if the PDS already exists */                                      
  14003.                                                                                 
  14004.      if (nnexdsn[0] != '\'') {                                                  
  14005.        strcpy(quoted_dsname,"'");                                               
  14006.        strcat(quoted_dsname,nnexdsn);                                           
  14007.        strcat(quoted_dsname,"'");                                               
  14008.      }                                                                          
  14009.      else strcpy(quoted_dsname,nnexdsn);                                        
  14010.                                                                                 
  14011.      /* Check if PDS already exists. */                                         
  14012.                                                                                 
  14013.      if (np->warn_overwrite) {                                                  
  14014.        xfp = fopen(quoted_dsname,"r");                                          
  14015.        if (xfp) {                                                               
  14016.          (void)fclose(xfp);                                                     
  14017.          xfp = NULL;                                                            
  14018.          if (NNMdispl(np,"NNMPEXPW") > 0) {                                     
  14019.            WARN1("Operation cancelled, because you pressed END.");              
  14020.            break;                                                               
  14021.          }                                                                      
  14022.        }                                                                        
  14023.      }                                                                          
  14024.                                                                                 
  14025.      if (!NNMalloc(nnexdsn,ep->ddname,PDS,ep->article_count)) {                 
  14026.        ERR2("Allocation failed for data set %s.", nnexdsn);                     
  14027.        xfp = NULL;                                                              
  14028.        continue;                                                                
  14029.      }                                                                          
  14030.      strcpy(ep->dsname,    nnexdsn);                                            
  14031.    }                                                                            
  14032.    else {                                                                       
  14033.      strcpy(ep->separator, nnexsep);                                            
  14034.      strcpy(ep->dsname,    nnexdsn);                                            
  14035.      ep->appending = (nnexapp[0] == 'Y');                                       
  14036.      ep->blanking  = (nnexblk[0] == 'Y');                                       
  14037.    }                                                                            
  14038.                                                                                 
  14039.    ep->tab_expanding = (nnextab[0] == 'Y');                                     
  14040.    if (*nnexan1) ep->from_article_number = atoi(nnexan1);                       
  14041.    else          ep->from_article_number = 0;                                   
  14042.    if (*nnexan2) ep->to_article_number   = atoi(nnexan2);                       
  14043.    else          ep->to_article_number   = INT_MAX;                             
  14044.                                                                                 
  14045.    /* check if the dataset already exists */                                    
  14046.    /* (Wonder if this will compile.  Have fun, "cc"...) */                      
  14047.                                                                                 
  14048.    if (ep->appending ? np->warn_append : np->warn_overwrite) {                  
  14049.      xfp = fopen(nnexdsn,"r");                                                  
  14050.      if (xfp) {                                                                 
  14051.        (void)fclose(xfp);                                                       
  14052.        xfp = NULL;                                                              
  14053.        if (NNMdispl(np,"NNMPEXOW") > 0) {                                       
  14054.          WARN1("Operation cancelled, because you pressed END.");                
  14055.          break;                                                                 
  14056.        }                                                                        
  14057.      }                                                                          
  14058.    }                                                                            
  14059.                                                                                 
  14060.    if (ep->mode == PDS) {                                                       
  14061.      xfp = DUMMY_FILE_POINTER_FOR_PDS;                                          
  14062.      break;                                                                     
  14063.    }                                                                            
  14064.                                                                                 
  14065.    xfp = OPEN_TEXT_FILE_FOR_WRITE_OR_APPEND(nnexdsn,ep->appending);             
  14066.                                                                                 
  14067.    if (!xfp) {                                                                  
  14068.      fprintf(stderr,"Open failure: errno=%d\n",errno);                          
  14069.      perror(nnexdsn);                                                           
  14070.      ERR2("Cannot open data set %s.", ep->dsname);                              
  14071.    }                                                                            
  14072.  }                                                                              
  14073.                                                                                 
  14074.  (void)NNMispf(np,"REMPOP");                                                    
  14075.                                                                                 
  14076.  return xfp;                                                                    
  14077.                                                                                 
  14078. }                                                                               
  14079.                                                                                 
  14080. ./   ADD NAME=NNMGETM,SSI=01030037                                              
  14081.                                                                                 
  14082.  /********************************************************************/         
  14083.  /*                                                                  */         
  14084.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  14085.  /*                                                                  */         
  14086.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  14087.  /* including the implied warranties of merchantability and fitness, */         
  14088.  /* are expressly denied.                                            */         
  14089.  /*                                                                  */         
  14090.  /* Provided this copyright notice is included, this software may    */         
  14091.  /* be freely distributed and not offered for sale.                  */         
  14092.  /*                                                                  */         
  14093.  /* Changes or modifications may be made and used only by the maker  */         
  14094.  /* of same, and not further distributed.  Such modifications should */         
  14095.  /* be mailed to the author for consideration for addition to the    */         
  14096.  /* software and incorporation in subsequent releases.               */         
  14097.  /*                                                                  */         
  14098.  /********************************************************************/         
  14099.                                                                                 
  14100. #pragma  csect(code,  "NN@GETM ")                                               
  14101. #pragma  csect(static,"NN$GETM ")                                               
  14102. #include "nn.h"                                                                 
  14103.                                                                                 
  14104. /****** Get memory. **************************************************/         
  14105.                                                                                 
  14106. void                                                                            
  14107. NNMgetm(np,pointer,howmuch,whatfor)                                             
  14108. Rstruc nncb    *np;                                                             
  14109. char          **pointer;                                                        
  14110. int             howmuch;                                                        
  14111. char           *whatfor;                                                        
  14112. {                                                                               
  14113.                                                                                 
  14114.  *pointer = (char *)malloc(howmuch);                                            
  14115.                                                                                 
  14116.  if (*pointer == NULL) {                                                        
  14117.    fprintf(stderr,"get_mem: Cannot obtain %d bytes of memory for %s\n",         
  14118.                   howmuch,whatfor);                                             
  14119.  }                                                                              
  14120.  else if (np->debug_file) {                                                     
  14121.    fprintf(np->debug_file,"getmem: got %d bytes of memory for %s\n",            
  14122.                            howmuch,whatfor);                                    
  14123.  }                                                                              
  14124.  return;                                                                        
  14125.                                                                                 
  14126. }                                                                               
  14127.                                                                                 
  14128. ./   ADD NAME=NNMGSRVL,SSI=010E0007                                             
  14129.                                                                                 
  14130.  /********************************************************************/         
  14131.  /*                                                                  */         
  14132.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  14133.  /*                                                                  */         
  14134.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  14135.  /* including the implied warranties of merchantability and fitness, */         
  14136.  /* are expressly denied.                                            */         
  14137.  /*                                                                  */         
  14138.  /* Provided this copyright notice is included, this software may    */         
  14139.  /* be freely distributed and not offered for sale.                  */         
  14140.  /*                                                                  */         
  14141.  /* Changes or modifications may be made and used only by the maker  */         
  14142.  /* of same, and not further distributed.  Such modifications should */         
  14143.  /* be mailed to the author for consideration for addition to the    */         
  14144.  /* software and incorporation in subsequent releases.               */         
  14145.  /*                                                                  */         
  14146.  /********************************************************************/         
  14147.                                                                                 
  14148. #pragma  csect(code,  "NN@GSRVL")                                               
  14149. #pragma  csect(static,"NN$GSRVL")                                               
  14150. #include "nn.h"                                                                 
  14151.                                                                                 
  14152. /****** Input one character from the server. *************************/         
  14153.                                                                                 
  14154. static int                                                                      
  14155. socket_getchar(np)                                                              
  14156. Rstruc nncb  *np;                                                               
  14157. {                                                                               
  14158.  int         readrc;                                                            
  14159.                                                                                 
  14160.  if (np->g_buf_index == -1 ||                                                   
  14161.      np->g_buf_index >= np->g_bytes_returned - 1) {                             
  14162.    np->g_buf_index = -1;                                                        
  14163.    if (np->dont_read) return(SOCKET_NO_MORE);                                   
  14164.    else {                                                                       
  14165.      TCP_DEBUG_ON;                                                              
  14166.      readrc = read(np->socknum, np->g_buf, READ_BYTES);                         
  14167.      TCP_DEBUG_OFF;                                                             
  14168.      if (readrc == -1) {                                                        
  14169.        np->connection_broken = TRUE;                                            
  14170.        return SOCKET_GETCHAR_ERROR;                                             
  14171.      }                                                                          
  14172.      else if (readrc == 0) {                                                    
  14173.        np->connection_broken = TRUE;                                            
  14174.        return SOCKET_READ_NOTHING;                                              
  14175.      }                                                                          
  14176.      else {                                                                     
  14177. #ifdef MVS                                                                      
  14178.        int i;                                                                   
  14179.        for (i=0;i<readrc;i++) np->g_buf[i] = atoe(np->g_buf[i]);                
  14180. #endif                                                                          
  14181.        np->g_bytes_returned = readrc;                                           
  14182.      }                                                                          
  14183.    }                                                                            
  14184.  }                                                                              
  14185.  return np->g_buf[++np->g_buf_index];                                           
  14186. }                                                                               
  14187.                                                                                 
  14188. /****** Input one data line at a time from the server. ***************/         
  14189.                                                                                 
  14190. static enum socket_retval                                                       
  14191. socket_from_server(np)                                                          
  14192. Rstruc nncb *np;                                                                
  14193. {                                                                               
  14194.  char       *s_buf;                                                             
  14195.  int         s_bytes;                                                           
  14196.  int         s_buf_index;                                                       
  14197.  int         character;                                                         
  14198.  int         previous_character;                                                
  14199.                                                                                 
  14200.  s_buf   = np->server_buf;                                                      
  14201.  s_bytes = SERVER_BUF_MSGSIZE;                                                  
  14202.                                                                                 
  14203.  /* Get characters from the server until CRLF is reached. */                    
  14204.                                                                                 
  14205.  s_buf_index = 0;                                                               
  14206.  previous_character = -1;                                                       
  14207.  for (;;) {                                                                     
  14208.    character = socket_getchar(np);                                              
  14209.    if (character == LINE_FEED && previous_character == CARRIAGE_RETURN)         
  14210.       break;                                                                    
  14211.    if (character == SOCKET_GETCHAR_ERROR)  return(SERVER_READ_ERROR);           
  14212.    if (character == SOCKET_NO_MORE)        return(SERVER_NO_MORE);              
  14213.    if (character == SOCKET_READ_NOTHING)   return(SERVER_READ_ERROR);           
  14214.    previous_character = character;                                              
  14215.    if (s_buf_index >= s_bytes) {                                                
  14216.      fprintf(stderr,"Error: np->server_buf overflowed.\n");                     
  14217.      fprintf(stderr,                                                            
  14218.              "More than %d bytes collected without CR/LF seen.\n",              
  14219.              s_bytes);                                                          
  14220.      if (np->debug_file) {                                                      
  14221.        NNMdump(np,"Data collected so far",np->server_buf,s_bytes);              
  14222.      }                                                                          
  14223.      return(SERVER_BUFFER_ERROR);                                               
  14224.    }                                                                            
  14225.    if (character == '\0') {                                                     
  14226.      fprintf(stderr,                                                            
  14227. "Warning: null character found in data from server, changed to blank\n"         
  14228.             );                                                                  
  14229.      character = ' ';                                                           
  14230.    }                                                                            
  14231.    s_buf[s_buf_index++] = (unsigned char)character;                             
  14232.  }                                                                              
  14233.  s_buf[s_buf_index] = '\0';                                                     
  14234.  return(SERVER_READ_OK);                                                        
  14235. }                                                                               
  14236.                                                                                 
  14237. /****** Get server line. *********************************************/         
  14238.                                                                                 
  14239. Bool                                                                            
  14240. NNMgsrvl(np,pointer)                                                            
  14241. Rstruc nncb  *np;                                                               
  14242. char        **pointer;                                                          
  14243. {                                                                               
  14244.  char              *sbufp;                                                      
  14245.  char              *p;                                                          
  14246.  int                scan_count;                                                 
  14247.  int                tries;                                                      
  14248.                                                                                 
  14249.  *pointer = NULL;                                                               
  14250.                                                                                 
  14251.  if (np->receiving_text) { /* as when POSTing a news item... */                 
  14252.    return TRUE;                                                                 
  14253.  }                                                                              
  14254.                                                                                 
  14255.  if (np->server_finished_replying) np->dont_read = TRUE;                        
  14256.                                                                                 
  14257.  for (tries=0;tries<2;tries++) {                                                
  14258.                                                                                 
  14259.    switch (socket_from_server(np)) {                                            
  14260.      case SERVER_READ_OK:      break;                                           
  14261.      case SERVER_READ_ERROR:   ERR2(                                            
  14262.        "Lost server connection.  Failure reading data from server %s.",         
  14263.                                     np->nnserver);                              
  14264.                                np->time_to_go_home = TRUE;                      
  14265.                                break;                                           
  14266.      case SERVER_BUFFER_ERROR: ERR2(                                            
  14267.    "Read error.  No linefeed character found in data from server %s.",          
  14268.                                     np->nnserver);                              
  14269.                                np->time_to_go_home = TRUE;                      
  14270.                                break;                                           
  14271.      case SERVER_NO_MORE:      np->server_has_something_pending = FALSE;        
  14272.                                break;                                           
  14273.    }                                                                            
  14274.    if (np->connection_broken) {                                                 
  14275.      if (!np->closing_connection) {                                             
  14276.        if (!np->reconnect_in_progress) {                                        
  14277.          if (NNMrecon(np)) {    /* Reconnect to server */                       
  14278.            /* have to reissue most recently written command */                  
  14279.            if (NNMsockt(np)) {      /* Send socket command to server */         
  14280.              WARN2(                                                             
  14281.             "Successfully reconnected to server %s after disconnect.",          
  14282.                    np->nnserver);                                               
  14283.              continue;                                                          
  14284.            }                                                                    
  14285.          }                                                                      
  14286.        }                                                                        
  14287.      }                                                                          
  14288.    }                                                                            
  14289.    break;                                                                       
  14290.  }                                                                              
  14291.                                                                                 
  14292.  if (np->time_to_go_home == TRUE) return FALSE;                                 
  14293.  if (np->dont_read == TRUE &&                                                   
  14294.      np->server_has_something_pending == FALSE) return TRUE;                    
  14295.                                                                                 
  14296.  np->something_to_print = TRUE;                                                 
  14297.                                                                                 
  14298.  sbufp = np->server_buf;                                                        
  14299.                                                                                 
  14300.  if (np->sending_text == TRUE) {                                                
  14301.    if (*sbufp == '.') {                                                         
  14302.      /*                                                                         
  14303.      NNMdump(np,"Line that starts with a period",sbufp,strlen(sbufp));          
  14304.      */                                                                         
  14305.      switch (*(sbufp+1)) {                                                      
  14306.         case CARRIAGE_RETURN:                                                   
  14307.         case LINE_FEED:                                                         
  14308.         case '\0':                                                              
  14309.                   np->server_finished_replying = TRUE;                          
  14310.                /* np->something_to_print = FALSE; */                            
  14311.                   break;                                                        
  14312.         case '.':                                                               
  14313.                   break;                                                        
  14314.         default:                                                                
  14315.                   NNMdump(np,"Warning, bad period in line from server",         
  14316.                           sbufp,strlen(sbufp));                                 
  14317.                   break;                                                        
  14318.      }                                                                          
  14319.    }                                                                            
  14320.    else /* nothing - still sending that there text */ ;                         
  14321.                                                                                 
  14322.    np->nntp_message_num  = NO_NNTP_MESSAGE_NUM;                                 
  14323.    np->nntp_message_text = sbufp;                                               
  14324.  }                                                                              
  14325.  else {                                                                         
  14326.        np->nntp_message_num = NO_NNTP_MESSAGE_NUM;                              
  14327.        scan_count = 0;                                                          
  14328.        sscanf(sbufp,"%d %n",&np->nntp_message_num,&scan_count);                 
  14329.        np->nntp_message_text = sbufp + scan_count;                              
  14330.        /*                                                                       
  14331.        NNMdump(np,"message_num", np->nntp_message_num, -2);                     
  14332.        NNMdump(np,"message_text",np->nntp_message_text,-1);                     
  14333.        */                                                                       
  14334.        switch (np->nntp_message_num) {                                          
  14335.           case 205:                                                             
  14336.           case 400:                                                             
  14337.        /* case 502: */                                                          
  14338.                    np->server_finished_replying = TRUE;                         
  14339.                    np->time_to_go_home = TRUE;                                  
  14340.                    break;                                                       
  14341.           case 335:                                                             
  14342.           case 340:                                                             
  14343.                    np->server_finished_replying = TRUE;                         
  14344.                    np->receiving_text = TRUE;                                   
  14345.                    break;                                                       
  14346.           case 100:                                                             
  14347.           case 199:                                                             
  14348.           case 215:                                                             
  14349.           case 220:                                                             
  14350.           case 221:                                                             
  14351.           case 222:                                                             
  14352.           case 230:                                                             
  14353.           case 231:                                                             
  14354.                    np->sending_text = TRUE;                                     
  14355.                    break;                                                       
  14356.           case NO_NNTP_MESSAGE_NUM:                                             
  14357.                    fprintf(stderr,                                              
  14358.     "Error: No NNTP message ID number in response from server %s.\n",           
  14359.                                   np->nnserver);                                
  14360.                    np->sending_text = TRUE;                                     
  14361.                    np->receiving_text = FALSE;                                  
  14362.                    break;                                                       
  14363.           default:                                                              
  14364.                    np->server_finished_replying = TRUE;                         
  14365.                    break;                                                       
  14366.    }                                                                            
  14367.  }                                                                              
  14368.                                                                                 
  14369.  if (np->something_to_print == TRUE) {                                          
  14370.    /* Last character of output buffer is a CR without LF. */                    
  14371.    p = sbufp + strlen(sbufp)-1;                                                 
  14372.    if (p >= sbufp) {                                                            
  14373.      if (*p == CARRIAGE_RETURN) *p = '\0';                                      
  14374.      else {                                                                     
  14375.        fprintf(stderr,                                                          
  14376.    "Warning: No carriage return in data from server (%d bytes):\n%s\n",         
  14377.                strlen(sbufp), sbufp);                                           
  14378.          CRIT2(                                                                 
  14379. "Carriage return expected but not seen in data from server %s.",                
  14380.                np->nnserver);                                                   
  14381.           }                                                                     
  14382.    }                                                                            
  14383.    *pointer = sbufp;                                                            
  14384.  }                                                                              
  14385.                                                                                 
  14386.  if (np->time_to_go_home == TRUE) return FALSE;                                 
  14387.  else return TRUE;                                                              
  14388. }                                                                               
  14389.                                                                                 
  14390. ./   ADD NAME=NNMIERR,SSI=01030010                                              
  14391.                                                                                 
  14392.  /********************************************************************/         
  14393.  /*                                                                  */         
  14394.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  14395.  /*                                                                  */         
  14396.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  14397.  /* including the implied warranties of merchantability and fitness, */         
  14398.  /* are expressly denied.                                            */         
  14399.  /*                                                                  */         
  14400.  /* Provided this copyright notice is included, this software may    */         
  14401.  /* be freely distributed and not offered for sale.                  */         
  14402.  /*                                                                  */         
  14403.  /* Changes or modifications may be made and used only by the maker  */         
  14404.  /* of same, and not further distributed.  Such modifications should */         
  14405.  /* be mailed to the author for consideration for addition to the    */         
  14406.  /* software and incorporation in subsequent releases.               */         
  14407.  /*                                                                  */         
  14408.  /********************************************************************/         
  14409.                                                                                 
  14410. #pragma  csect(code,  "NN@IERR ")                                               
  14411. #pragma  csect(static,"NN$IERR ")                                               
  14412. #include "nn.h"                                                                 
  14413.                                                                                 
  14414. /****** ISPF error handler. ******************************************/         
  14415.                                                                                 
  14416. void                                                                            
  14417. NNMierr(np)                                                                     
  14418. Rstruc nncb *np;                                                                
  14419. {                                                                               
  14420.  char        errbuf[] = "DISPLAY PANEL(ISPTERM)";                               
  14421.  int         errlen;                                                            
  14422.                                                                                 
  14423.  if (np->batch_mode) {                                                          
  14424.    fprintf(stderr,"ISPF services cannot be called from batch mode.\n");         
  14425.    return;                                                                      
  14426.  }                                                                              
  14427.                                                                                 
  14428.  errlen = strlen(errbuf);                                                       
  14429.  switch (ISPEXEC(&errlen,errbuf)) {                                             
  14430.    case  0:                                                                     
  14431.    case  4:                                                                     
  14432.    case  8:                                                                     
  14433.            return;                                                              
  14434.    default:                                                                     
  14435.            fprintf(stderr,                                                      
  14436. "\n*** Severe ISPF error, cannot even display ISPTERM error panel.\n");         
  14437.            fprintf(stderr,                                                      
  14438. "\n*** Return code from ISPF service is %d\n",np->ispfrc);                      
  14439.            return;                                                              
  14440.  }                                                                              
  14441. }                                                                               
  14442.                                                                                 
  14443. ./   ADD NAME=NNMIGET,SSI=01040034                                              
  14444.                                                                                 
  14445.  /********************************************************************/         
  14446.  /*                                                                  */         
  14447.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  14448.  /*                                                                  */         
  14449.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  14450.  /* including the implied warranties of merchantability and fitness, */         
  14451.  /* are expressly denied.                                            */         
  14452.  /*                                                                  */         
  14453.  /* Provided this copyright notice is included, this software may    */         
  14454.  /* be freely distributed and not offered for sale.                  */         
  14455.  /*                                                                  */         
  14456.  /* Changes or modifications may be made and used only by the maker  */         
  14457.  /* of same, and not further distributed.  Such modifications should */         
  14458.  /* be mailed to the author for consideration for addition to the    */         
  14459.  /* software and incorporation in subsequent releases.               */         
  14460.  /*                                                                  */         
  14461.  /********************************************************************/         
  14462.                                                                                 
  14463. #pragma  csect(code,  "NN@IGET ")                                               
  14464. #pragma  csect(static,"NN$IGET ")                                               
  14465. #include "nn.h"                                                                 
  14466.                                                                                 
  14467. /****** Retrieve the value of an ISPF variable into an integer. ******/         
  14468.                                                                                 
  14469. int                                                                             
  14470. NNMiget(np,varname)                                                             
  14471. Rstruc nncb *np;                                                                
  14472. char        *varname;                                                           
  14473. {                                                                               
  14474.  char        varbuf[16];                                                        
  14475.  int         vcopy_length;                                                      
  14476.                                                                                 
  14477.  if (!strchr(varname,' ')) {                                                    
  14478.    fprintf(stderr,"NNMiget: no blank passed in var name\n");                    
  14479.    return FALSE;                                                                
  14480.  }                                                                              
  14481.                                                                                 
  14482.  vcopy_length = sizeof(varbuf);                                                 
  14483.                                                                                 
  14484.  np->ispfrc = ISPLINK("VCOPY",varname,&vcopy_length,varbuf,"MOVE");             
  14485.  switch (np->ispfrc) {                                                          
  14486.    case  0:                                                                     
  14487.            varbuf[vcopy_length] = '\0';                                         
  14488.            return atoi(varbuf);                                                 
  14489.    case  8:                                                                     
  14490.            return 0;                                                            
  14491.    case 16:                                                                     
  14492.            fprintf(stderr,                                                      
  14493.                    "Error: ISPF variable buffer too short to get %s\n",         
  14494.                    varname);                                                    
  14495.            return 0;                                                            
  14496.    default:                                                                     
  14497.            NNMierr(np);   /* handle ISPF error */                               
  14498.            return 0;                                                            
  14499.  }                                                                              
  14500. }                                                                               
  14501.                                                                                 
  14502. ./   ADD NAME=NNMINIT,SSI=01630022                                              
  14503.                                                                                 
  14504.  /********************************************************************/         
  14505.  /*                                                                  */         
  14506.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  14507.  /*                                                                  */         
  14508.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  14509.  /*                                                                  */         
  14510.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  14511.  /* including the implied warranties of merchantability and fitness, */         
  14512.  /* are expressly denied.                                            */         
  14513.  /*                                                                  */         
  14514.  /* Provided this copyright notice is included, this software may    */         
  14515.  /* be freely distributed and not offered for sale.                  */         
  14516.  /*                                                                  */         
  14517.  /* Changes or modifications may be made and used only by the maker  */         
  14518.  /* of same, and not further distributed.  Such modifications should */         
  14519.  /* be mailed to the author for consideration for addition to the    */         
  14520.  /* software and incorporation in subsequent releases.               */         
  14521.  /*                                                                  */         
  14522.  /********************************************************************/         
  14523.                                                                                 
  14524. #pragma  csect(code,  "NN@INIT ")                                               
  14525. #pragma  csect(static,"NN$INIT ")                                               
  14526. #include "nn.h"                                                                 
  14527.                                                                                 
  14528. #define ARGSIZE            72                                                   
  14529. #define ISPF_WHITESPACE    " ,\t"                                               
  14530.                                                                                 
  14531. #define clear_subject(X)   *(X)->selsubj = '\0'                                 
  14532.                                                                                 
  14533. enum getop_option {                                                             
  14534.                    GETOP_NOMORE,                                                
  14535.                    GETOP_ASIS,                                                  
  14536.                    GETOP_UPPERCASE,                                             
  14537.                    GETOP_LOWERCASE,                                             
  14538.                    GETOP_INTEGER                                                
  14539.                   };                                                            
  14540.                                                                                 
  14541. /****** Get the next operand of the command. *************************/         
  14542.                                                                                 
  14543. static Bool                                                                     
  14544. getop(np,bufpp,argp,option)                                                     
  14545. Rstruc nncb            *np;                                                     
  14546. char                  **bufpp;                                                  
  14547. char                   *argp;                                                   
  14548. enum getop_option       option;                                                 
  14549. {                                                                               
  14550.  register char         *icp;                                                    
  14551.  register char         *ocp;                                                    
  14552.  register int           olen;                                                   
  14553.  int                    maxlen;                                                 
  14554.  char                   quote;                                                  
  14555.  char                   work[12];                                               
  14556.                                                                                 
  14557.  icp = *bufpp + strspn(*bufpp,ISPF_WHITESPACE);                                 
  14558.  if (!*icp) {                          /* if reached end of buffer  */          
  14559.    *bufpp = icp;                                                                
  14560.    switch (option) {                                                            
  14561.      case GETOP_NOMORE:  return TRUE;            /* indicate no more */         
  14562.      case GETOP_INTEGER: ERR1("A numeric integer value is required.");          
  14563.                          return FALSE;                                          
  14564.      default:            *argp = '\0';  /* set operand to null string*/         
  14565.                          return TRUE;                                           
  14566.    }                                                                            
  14567.  }                                                                              
  14568.                                                                                 
  14569.  /* icp points to next argument in buffer */                                    
  14570.                                                                                 
  14571.  if (option == GETOP_NOMORE) return FALSE;   /* too many operands */            
  14572.                                                                                 
  14573.  if (option == GETOP_INTEGER) {                                                 
  14574.    ocp = work;                                                                  
  14575.    maxlen = sizeof(work);                                                       
  14576.    quote = '\0';                                                                
  14577.   }                                                                             
  14578.  else {                                                                         
  14579.    ocp = argp;                                                                  
  14580.    maxlen = ARGSIZE;                                                            
  14581.    switch (*icp) {                                                              
  14582.      case '\'':                                                                 
  14583.      case '"' :  quote = *icp; break;                                           
  14584.      default:    quote = '\0'; break;                                           
  14585.    }                                                                            
  14586.  }                                                                              
  14587.                                                                                 
  14588.  if (quote) {                                                                   
  14589.    for (icp++,olen=0;                                                           
  14590.         ;                                                                       
  14591.         icp++,ocp++,olen++) {                                                   
  14592.      if (*icp == '\0') {                                                        
  14593.        ERR1("Beginning quote mark not matched by ending quote mark.");          
  14594.        *bufpp = icp;                                                            
  14595.        return FALSE;                                                            
  14596.      }                                                                          
  14597.      if (*icp == quote) {                                                       
  14598.        if (*(++icp) != quote) {                                                 
  14599.          *bufpp = icp;                                                          
  14600.          break;                                                                 
  14601.        }                                                                        
  14602.      }                                                                          
  14603.      if (olen <= maxlen) {                                                      
  14604.        switch (option) {                                                        
  14605.          case GETOP_LOWERCASE:  *ocp = tolower(*icp); break;                    
  14606.          case GETOP_UPPERCASE:  *ocp = toupper(*icp); break;                    
  14607.          default:               *ocp = *icp;          break;                    
  14608.        }                                                                        
  14609.      }                                                                          
  14610.    }                                                                            
  14611.    if (olen > maxlen) {                                                         
  14612.      ERR2("An operand longer than %d characters is not valid.", maxlen);        
  14613.      return FALSE;                                                              
  14614.    }                                                                            
  14615.  }                                                                              
  14616.  else {                                                                         
  14617.    *bufpp = strpbrk(icp,ISPF_WHITESPACE);   /* find end of word */              
  14618.    if (!*bufpp) *bufpp = strchr(icp,'\0');                                      
  14619.    olen = *bufpp - icp;                                                         
  14620.                                                                                 
  14621.    if (olen > maxlen) {                                                         
  14622.      ERR2("An operand longer than %d characters is not valid.", maxlen);        
  14623.      return FALSE;                                                              
  14624.    }                                                                            
  14625.                                                                                 
  14626.    switch (option) {                                                            
  14627.      case GETOP_LOWERCASE:                                                      
  14628.                            while (olen--) *ocp++ = tolower(*icp++);             
  14629.                            break;                                               
  14630.      case GETOP_UPPERCASE:                                                      
  14631.                            while (olen--) *ocp++ = toupper(*icp++);             
  14632.                            break;                                               
  14633.      default:                                                                   
  14634.                            while (olen--) *ocp++ = *icp++;                      
  14635.                            break;                                               
  14636.    }                                                                            
  14637.  }                                                                              
  14638.                                                                                 
  14639.  *ocp = '\0';                                                                   
  14640.                                                                                 
  14641.  if (option == GETOP_INTEGER) {                                                 
  14642.    if (*(work + strspn(work,"0123456789"))) {                                   
  14643.      ERR1("A numeric integer value is required.");                              
  14644.      return FALSE;                                                              
  14645.    }                                                                            
  14646.    *(int *)argp = atoi(work);                                                   
  14647.  }                                                                              
  14648.                                                                                 
  14649.  return TRUE;                                                                   
  14650.                                                                                 
  14651. }                                                                               
  14652.                                                                                 
  14653. /****** Subject compare, for locating by subject. ********************/         
  14654.                                                                                 
  14655. /* May want to emulate NNMstrlc for more efficiency.  All that is               
  14656.  * needed is to add code to NNMstrlc to strip re's.                             
  14657.  */                                                                             
  14658.                                                                                 
  14659. int                                                                             
  14660. subjectcmp(a,b)                                                                 
  14661. char        *a;                                                                 
  14662. char        *b;                                                                 
  14663. {                                                                               
  14664.  char       *cp;                                                                
  14665.  char       *c1;                                                                
  14666.  char       *c2;                                                                
  14667.  int         re_count_1;                                                        
  14668.  int         re_count_2;                                                        
  14669.  int         answer;                                                            
  14670.  char        s2[257];                                                           
  14671.                                                                                 
  14672.  /* arg 1 already lowercased */                                                 
  14673.                                                                                 
  14674.  strncpy(s2,b,256);                                                             
  14675.                                                                                 
  14676.  for (cp=s2; *cp; cp++) *cp = tolower(*cp);                                     
  14677.  for (; cp > s2 && isspace(*(cp-1)); cp--);                                     
  14678.  *cp = '\0';                                                                    
  14679.                                                                                 
  14680.  c1 = a;                                                                        
  14681.  c2 = s2;                                                                       
  14682.                                                                                 
  14683.  re_count_1 = 0;                                                                
  14684.  while (!memcmp(c1,"re:",3)) {                                                  
  14685.    c1 = c1 + 3 + strspn(c1+3," \t");                                            
  14686.    re_count_1++;                                                                
  14687.  }                                                                              
  14688.  re_count_2 = 0;                                                                
  14689.  while (!memcmp(c2,"re:",3)) {                                                  
  14690.    c2 = c2 + 3 + strspn(c2+3," \t");                                            
  14691.    re_count_2++;                                                                
  14692.  }                                                                              
  14693.                                                                                 
  14694.  if ((answer=strcmp(c1,c2)) != 0) return answer;                                
  14695.  else return re_count_1 - re_count_2;                                           
  14696.                                                                                 
  14697. }                                                                               
  14698.                                                                                 
  14699. /****** Retrieve all article titles. *********************************/         
  14700.                                                                                 
  14701. static void                                                                     
  14702. retrieve_all_article_titles(np,gp)                                              
  14703. Rstruc nncb         *np;                                                        
  14704. Rstruc newsgroup    *gp;                                                        
  14705. {                                                                               
  14706.  Rstruc newsarticle *ap;                                                        
  14707.  struct countdown    cd;                                                        
  14708.                                                                                 
  14709.   np->bypass_header_retrieval = FALSE;                                          
  14710.                                                                                 
  14711.   if (!gp->first_article) return;                                               
  14712.                                                                                 
  14713.   if (np->updatefreq < 0) {                                                     
  14714.     cd.do_update = FALSE;                                                       
  14715.     cd.done      = 0;                                                           
  14716.     cd.to_do     = 0;                                                           
  14717.   }                                                                             
  14718.   else {                                                                        
  14719.     cd.do_update = TRUE;                                                        
  14720.     cd.done      = 0;                                                           
  14721.     cd.to_do     = 0;                                                           
  14722.     for (ap = gp->first_article; ap <= gp->real_last_article; ap++) {           
  14723.       if (ArticleInTable(ap)) cd.to_do++;                                       
  14724.     }                                                                           
  14725.     if (cd.to_do == 0) return;                                                  
  14726.   }                                                                             
  14727.                                                                                 
  14728.   ap = gp->first_article;                                                       
  14729.   while (ap <= gp->real_last_article) {                                         
  14730.     if (ArticleInTable(ap)) {                                                   
  14731.       if (!NNMrarh(np,gp,ap,TRUE,&cd)) { /* Retrieve article header */          
  14732.         if (np->article_error_found) {                                          
  14733.           np->article_criterion_changed = TRUE;                                 
  14734.           ap = gp->first_article;                                               
  14735.           continue;                                                             
  14736.         }                                                                       
  14737.       }                                                                         
  14738.     }                                                                           
  14739.     ap++;                                                                       
  14740.   }                                                                             
  14741.                                                                                 
  14742.  return;                                                                        
  14743. }                                                                               
  14744.                                                                                 
  14745. /****** Mark all articles read. **************************************/         
  14746.                                                                                 
  14747. static Bool                                                                     
  14748. mark_all_articles_read(np,gp,prompt)                                            
  14749. Rstruc nncb          *np;                                                       
  14750. Rstruc newsgroup     *gp;                                                       
  14751. Fool                  prompt;                                                   
  14752. {                                                                               
  14753.  int                  n;                                                        
  14754.  int                  prc;                                                      
  14755.  VARK                *vp;                                                       
  14756.                                                                                 
  14757.  /* Display panel asking if user really wants to do this. */                    
  14758.                                                                                 
  14759.  if (prompt && !np->batch_mode) {                                               
  14760.    (void)NNMivput(np,"NNMARK ","Read",-1);                                      
  14761.    (void)NNMispf(np,"ADDPOP");                                                  
  14762.    prc = NNMdispl(np,"NNMPMARK");                                               
  14763.    (void)NNMispf(np,"REMPOP");                                                  
  14764.    if (prc > 0) { /* see if user pressed END */                                 
  14765.      WARN1("Operation cancelled, because you pressed END.");                    
  14766.      return TRUE;                                                               
  14767.    }                                                                            
  14768.  }                                                                              
  14769.                                                                                 
  14770.  (void)NNMallav(np,gp);                  /* Allocate article vector */          
  14771.                                                                                 
  14772.  for (n=0; n<gp->article_vector_len; n++) {                                     
  14773.    vp = &gp->article_vector[n];                                                 
  14774.    switch (*vp) {                                                               
  14775.      case V_UNREAD:           *vp = V_READ;         break;                      
  14776.      case V_MISSING_UNREAD:   *vp = V_MISSING_READ; break;                      
  14777.    }                                                                            
  14778.  }                                                                              
  14779.                                                                                 
  14780.  gp->fake_unread_count = 0;                                                     
  14781.  gp->real_unread_count = 0;                                                     
  14782.                                                                                 
  14783.  WARN2("All of the articles in %s are now marked READ.",                        
  14784.        gp->name);                                                               
  14785.                                                                                 
  14786.  return TRUE;                                                                   
  14787. }                                                                               
  14788.                                                                                 
  14789. /****** Mark all articles unread. ************************************/         
  14790.                                                                                 
  14791. static Bool                                                                     
  14792. mark_all_articles_unread(np,gp,prompt)                                          
  14793. Rstruc nncb          *np;                                                       
  14794. Rstruc newsgroup     *gp;                                                       
  14795. Fool                  prompt;                                                   
  14796. {                                                                               
  14797.  int                  prc;                                                      
  14798.  int                  n;                                                        
  14799.  int                  uc;                                                       
  14800.  VARK                *vp;                                                       
  14801.                                                                                 
  14802.  /* Display panel asking if user really wants to do this. */                    
  14803.                                                                                 
  14804.  if (prompt && !np->batch_mode) {                                               
  14805.    (void)NNMivput(np,"NNMARK ","Unread",-1);                                    
  14806.    (void)NNMispf(np,"ADDPOP");                                                  
  14807.    prc = NNMdispl(np,"NNMPMARK");                                               
  14808.    (void)NNMispf(np,"REMPOP");                                                  
  14809.    if (prc > 0) { /* see if user pressed END */                                 
  14810.      WARN1("Operation cancelled, because you pressed END.");                    
  14811.      return TRUE;                                                               
  14812.    }                                                                            
  14813.  }                                                                              
  14814.                                                                                 
  14815.  (void)NNMallav(np,gp);                  /* Allocate article vector */          
  14816.                                                                                 
  14817.                                                                                 
  14818.  uc = 0;                                                                        
  14819.                                                                                 
  14820.  for (n=0; n<gp->article_vector_len; n++) {                                     
  14821.    vp = &gp->article_vector[n];                                                 
  14822.    switch (*vp) {                                                               
  14823.      case V_READ:           *vp = V_UNREAD;  uc++;  break;                      
  14824.      case V_MISSING_READ:   *vp = V_MISSING_UNREAD; break;                      
  14825.    }                                                                            
  14826.  }                                                                              
  14827.                                                                                 
  14828.  gp->fake_unread_count += uc;                                                   
  14829.  if (gp->real_unread_count == NO_VALUE)                                         
  14830.       gp->real_unread_count = gp->fake_unread_count;                            
  14831.  else gp->real_unread_count += uc;                                              
  14832.                                                                                 
  14833.  WARN2("All of the articles in %s are now marked UNREAD.",                      
  14834.        gp->name);                                                               
  14835.                                                                                 
  14836.  return TRUE;                                                                   
  14837. }                                                                               
  14838.                                                                                 
  14839. /****** Set subject. *************************************************/         
  14840.                                                                                 
  14841. static char *                                                                   
  14842. set_subject(np,ap)                                                              
  14843. Rstruc nncb         *np;                                                        
  14844. Rstruc newsarticle  *ap;                                                        
  14845. {                                                                               
  14846.  char               *cp;                                                        
  14847.  char               *s;                                                         
  14848.                                                                                 
  14849.  if (*np->selsubj) return np->selsubj;                                          
  14850.                                                                                 
  14851.  strncpy(np->selsubj, ap->subject, sizeof(np->selsubj)-1);                      
  14852.  s = np->selsubj;                                                               
  14853.  for (cp=s; *cp; cp++) *cp = tolower(*cp);                                      
  14854.  for (; cp > s && isspace(*cp-1); cp--);                                        
  14855.  *cp = '\0';                                                                    
  14856.  while (!memcmp(s,"re:",3)) {                                                   
  14857.    s = s+3 + strspn(s+3," \t");                                                 
  14858.  }                                                                              
  14859.                                                                                 
  14860.  return s;                                                                      
  14861.                                                                                 
  14862. }                                                                               
  14863.                                                                                 
  14864. /****** Process newsgroup LOCATE command. ****************************/         
  14865.                                                                                 
  14866. static Bool                                                                     
  14867. newsgroup_locate_command(np,gp,rest)                                            
  14868. Rstruc nncb         *np;                                                        
  14869. Rstruc newsgroup    *gp;                                                        
  14870. char                *rest;                                                      
  14871. {                                                                               
  14872.  char                string[ARGSIZE];                                           
  14873.                                                                                 
  14874.  /*                                                                             
  14875.   * Pass back the group name to position to.  NNMVNG will do the rest.          
  14876.   */                                                                            
  14877.                                                                                 
  14878.  if (!getop(np,&rest,&string,GETOP_LOWERCASE)) return FALSE;                    
  14879.                                                                                 
  14880.  if (!*string ||                                                                
  14881.      !getop(np,&rest,NULL,GETOP_NOMORE)) {                                      
  14882.    ERR1("The LOCATE command requires exactly one operand.");                    
  14883.    return FALSE;                                                                
  14884.  }                                                                              
  14885.                                                                                 
  14886.  strcpy(np->locate_string, string);                                             
  14887.                                                                                 
  14888.  np->please_locate_group = TRUE;                                                
  14889.                                                                                 
  14890.  return TRUE;                                                                   
  14891. }                                                                               
  14892.                                                                                 
  14893. /****** Process newsgroup ONLY command. ******************************/         
  14894.                                                                                 
  14895. static Bool                                                                     
  14896. newsgroup_only_command(np,gp,rest)                                              
  14897. Rstruc nncb         *np;                                                        
  14898. Rstruc newsgroup    *gp;                                                        
  14899. char                *rest;                                                      
  14900. {                                                                               
  14901.  char                string[ARGSIZE];                                           
  14902.                                                                                 
  14903.  if (!getop(np,&rest,&string,GETOP_LOWERCASE)) return FALSE;                    
  14904.                                                                                 
  14905.  if (!getop(np,&rest,NULL,GETOP_NOMORE)) {                                      
  14906.    ERR1(                                                                        
  14907. "The ONLY command may have only one operand.  Try quoting the string."          
  14908.        );                                                                       
  14909.    return FALSE;                                                                
  14910.  }                                                                              
  14911.                                                                                 
  14912.  strcpy(np->only_string, string);                                               
  14913.                                                                                 
  14914.  np->newsgroup_criterion_changed = TRUE;                                        
  14915.                                                                                 
  14916.  if (*np->only_string) {                                                        
  14917.    WARN2(                                                                       
  14918.     "To redisplay %s newsgroups, use ONLY command without operands.",           
  14919.          (np->show_all_newsgroups ? "all" : "all registered"));                 
  14920.  }                                                                              
  14921.                                                                                 
  14922.  return TRUE;                                                                   
  14923. }                                                                               
  14924.                                                                                 
  14925. /****** Process newsgroup FIND command. ******************************/         
  14926.                                                                                 
  14927. static Bool                                                                     
  14928. newsgroup_find_command(np,gp,rest)                                              
  14929. Rstruc nncb         *np;                                                        
  14930. Rstruc newsgroup    *gp;                                                        
  14931. char                *rest;                                                      
  14932. {                                                                               
  14933.  Bool                string_given;                                              
  14934.  Bool                option_given;                                              
  14935.  char                string [ARGSIZE];                                          
  14936.  char                option [ARGSIZE];                                          
  14937.                                                                                 
  14938.  /*                                                                             
  14939.   * Pass back the group name to position to.  NNMVNG will do the rest.          
  14940.   */                                                                            
  14941.                                                                                 
  14942.  if (!getop(np,&rest,&string,GETOP_LOWERCASE)) return FALSE;                    
  14943.  if (!getop(np,&rest,&option,GETOP_LOWERCASE)) return FALSE;                    
  14944.                                                                                 
  14945.  if (!getop(np,&rest,NULL,GETOP_NOMORE)) {                                      
  14946.    ERR1(                                                                        
  14947.     "Too many operands on the FIND command.  Try quoting the string.");         
  14948.    return FALSE;                                                                
  14949.  }                                                                              
  14950.                                                                                 
  14951.  string_given = *string;                                                        
  14952.  option_given = *option;                                                        
  14953.                                                                                 
  14954.  if (string_given) {                                                            
  14955.    strcpy(np->find_string,string);                                              
  14956.  }                                                                              
  14957.  else if (!*np->find_string) {                                                  
  14958.    ERR1(                                                                        
  14959.       "The FIND command requires a string the first time it is used.");         
  14960.    return FALSE;                                                                
  14961.  }                                                                              
  14962.                                                                                 
  14963.  if (option_given) {                                                            
  14964.    if      (EQUAL(option,"next"  )) np->find_option = FIND_NEXT;                
  14965.    else if (EQUAL(option,"first" )) np->find_option = FIND_FIRST;               
  14966.    else if (EQUAL(option,"prev"  )) np->find_option = FIND_PREV;                
  14967.    else if (EQUAL(option,"last"  )) np->find_option = FIND_LAST;                
  14968.    else {                                                                       
  14969.      ERR1("Unknown FIND option.  Specify NEXT, PREV, FIRST or LAST.");          
  14970.      return FALSE;                                                              
  14971.    }                                                                            
  14972.  }                                                                              
  14973.  else {                                                                         
  14974.    if (string_given) np->find_option = FIND_NEXT;                               
  14975.    else switch (np->find_option) {                                              
  14976.      case FIND_NEXT:  np->find_option = FIND_NEXT; break;                       
  14977.      case FIND_PREV:  np->find_option = FIND_PREV; break;                       
  14978.      case FIND_FIRST: np->find_option = FIND_NEXT; break;                       
  14979.      case FIND_LAST:  np->find_option = FIND_PREV; break;                       
  14980.      default:         np->find_option = FIND_NEXT; break;                       
  14981.    }                                                                            
  14982.  }                                                                              
  14983.                                                                                 
  14984.  np->please_find_group = TRUE;                                                  
  14985.  np->repeat_find = (!string_given && !option_given);                            
  14986.                                                                                 
  14987.  return TRUE;                                                                   
  14988. }                                                                               
  14989.                                                                                 
  14990. /****** Process newsgroup EXTRACT command. ***************************/         
  14991.                                                                                 
  14992. static Bool                                                                     
  14993. newsgroup_extract_command(np,gp,rest)                                           
  14994. Rstruc nncb         *np;                                                        
  14995. struct newsgroup    *gp;                                                        
  14996. char                *rest;                                                      
  14997. {                                                                               
  14998.                                                                                 
  14999.  if (!getop(np,&rest,NULL,GETOP_NOMORE)) {                                      
  15000.    ERR1("The EXTRACT command does not accept any operands.");                   
  15001.    return FALSE;                                                                
  15002.  }                                                                              
  15003.                                                                                 
  15004.  return NNMxlist(np,rest);  /* Extract newsgroup listing */                     
  15005.                                                                                 
  15006. }                                                                               
  15007.                                                                                 
  15008. /****** Process newsgroup REG command. *******************************/         
  15009.                                                                                 
  15010. static Bool                                                                     
  15011. newsgroup_reg_command(np,gp,rest)                                               
  15012. Rstruc nncb         *np;                                                        
  15013. Rstruc newsgroup    *gp;                                                        
  15014. char                *rest;                                                      
  15015. {                                                                               
  15016.                                                                                 
  15017.  np->newsgroup_criterion_changed = TRUE;                                        
  15018.  np->show_all_newsgroups = FALSE;                                               
  15019.  if (*np->only_string) {                                                        
  15020.    WARN2(                                                                       
  15021.     "To redisplay %s newsgroups, use ONLY command without operands.",           
  15022.          (np->show_all_newsgroups ? "all" : "all registered"));                 
  15023.  }                                                                              
  15024.                                                                                 
  15025.  return TRUE;                                                                   
  15026. }                                                                               
  15027.                                                                                 
  15028. /****** Process newsgroup ALL command. *******************************/         
  15029.                                                                                 
  15030. static Bool                                                                     
  15031. newsgroup_all_command(np,gp,rest)                                               
  15032. Rstruc nncb         *np;                                                        
  15033. Rstruc newsgroup    *gp;                                                        
  15034. char                *rest;                                                      
  15035. {                                                                               
  15036.                                                                                 
  15037.  np->newsgroup_criterion_changed = TRUE;                                        
  15038.  np->show_all_newsgroups = TRUE;                                                
  15039.  if (*np->only_string) {                                                        
  15040.    WARN2(                                                                       
  15041.     "To redisplay %s newsgroups, use ONLY command without operands.",           
  15042.          (np->show_all_newsgroups ? "all" : "all registered"));                 
  15043.  }                                                                              
  15044.                                                                                 
  15045.  return TRUE;                                                                   
  15046. }                                                                               
  15047.                                                                                 
  15048. /****** Process newsgroup ORDER command. *****************************/         
  15049.                                                                                 
  15050. static Bool                                                                     
  15051. newsgroup_order_command(np,gp,rest)                                             
  15052. Rstruc nncb         *np;                                                        
  15053. Rstruc newsgroup    *gp;                                                        
  15054. char                *rest;                                                      
  15055. {                                                                               
  15056.  char                string[ARGSIZE];                                           
  15057.  char                order;                                                     
  15058.                                                                                 
  15059.  /* Usage: ORDER A   -  display newsgroups in alphabetical order                
  15060.   *        ORDER L   -  display newsgroups in NNTP list order                   
  15061.   *        ORDER N   -  display newsgroups in NEWSRC order                      
  15062.   */                                                                            
  15063.                                                                                 
  15064.  if (!getop(np,&rest,&string,GETOP_ASIS)) return FALSE;                         
  15065.                                                                                 
  15066.  if (!getop(np,&rest,NULL,GETOP_NOMORE)) {                                      
  15067.    ERR1(                                                                        
  15068.      "The ORDER command requires one operand: Alphabetical or List.");          
  15069.    return FALSE;                                                                
  15070.  }                                                                              
  15071.                                                                                 
  15072.  switch (string[0]) {                                                           
  15073.    case 'a':                                                                    
  15074.    case 'A': order = ALPHABETICAL_ORDER;  break;                                
  15075.    case 'l':                                                                    
  15076.    case 'L': order = NNTP_LIST_ORDER;     break;                                
  15077.    case 'n':                                                                    
  15078.    case 'N': order = NEWSRC_ORDER;        break;                                
  15079.    default:                                                                     
  15080.              ERR1(                                                              
  15081.      "The ORDER command requires one operand: Alphabetical or List.");          
  15082.                                           return FALSE;                         
  15083.  }                                                                              
  15084.                                                                                 
  15085.  if (order == NEWSRC_ORDER) {                                                   
  15086.    ERR1("Sorry, but NEWSRC order has not been implemented.");                   
  15087.    return FALSE;                                                                
  15088.  }                                                                              
  15089.                                                                                 
  15090.  if (order == NNTP_LIST_ORDER && !np->first_newsgroup_alt) {                    
  15091.    ERR1(                                                                        
  15092. "List order is valid only when newsgroup list retrieved from server."           
  15093.        );                                                                       
  15094.    return FALSE;                                                                
  15095.  }                                                                              
  15096.                                                                                 
  15097.  np->newsgroup_order_changed = TRUE;                                            
  15098.  np->newsgroup_order = order;                                                   
  15099.                                                                                 
  15100.  return TRUE;                                                                   
  15101. }                                                                               
  15102.                                                                                 
  15103. /****** Process article LOCATE command. ******************************/         
  15104.                                                                                 
  15105. static Bool                                                                     
  15106. article_locate_command(np,gp,rest)                                              
  15107. Rstruc nncb         *np;                                                        
  15108. Rstruc newsgroup    *gp;                                                        
  15109. char                *rest;                                                      
  15110. {                                                                               
  15111.  Rstruc newsarticle *ap;                                                        
  15112.  int                 lnum;                                                      
  15113.  char                string[ARGSIZE];                                           
  15114.                                                                                 
  15115.  if (np->sort_by_subject) {                                                     
  15116.    if (!getop(np,&rest,&string,GETOP_LOWERCASE)) return FALSE;                  
  15117.    if (!*string || !getop(np,&rest,NULL,GETOP_NOMORE)) {                        
  15118.      ERR1("The LOCATE command requires exactly one operand.");                  
  15119.      return FALSE;                                                              
  15120.    }                                                                            
  15121.    /* Position to article with subject closest to requested subject */          
  15122.    if (!(ap=gp->first_article)) return TRUE;                                    
  15123.    while (ap <= gp->real_last_article) {                                        
  15124.      if (subjectcmp(string,ap->subject) <= 0) break;                            
  15125.      ap++;                                                                      
  15126.    }                                                                            
  15127.  }                                                                              
  15128.  else {                                                                         
  15129.    if (!getop(np,&rest,(char *)&lnum,GETOP_INTEGER)) return FALSE;              
  15130.    if (!getop(np,&rest,NULL,GETOP_NOMORE)) {                                    
  15131.      ERR1("The LOCATE command requires exactly one operand.");                  
  15132.      return FALSE;                                                              
  15133.    }                                                                            
  15134.    /* Position to article with number closest to requested number */            
  15135.    if (!(ap=gp->first_article)) return TRUE;                                    
  15136.    while (ap <= gp->real_last_article) {                                        
  15137.      if (lnum <= ap->number) break;                                             
  15138.      ap++;                                                                      
  15139.    }                                                                            
  15140.  }                                                                              
  15141.                                                                                 
  15142.  if (!ap || ap > gp->real_last_article) {                                       
  15143.    np->top_article = PHONY_NEWS_ARTICLE;  /* force scroll to bottom */          
  15144.    return TRUE;                                                                 
  15145.  }                                                                              
  15146.                                                                                 
  15147.  np->top_article = ap;                                                          
  15148.                                                                                 
  15149.  /* Note: We don't worry about whether that article, or any of the              
  15150.   * articles between the current one and this one, are in the table.            
  15151.   * When NNMvar regenerates the display, it will know that the top              
  15152.   * article has changed and will figure it out.                                 
  15153.   */                                                                            
  15154.                                                                                 
  15155.  return TRUE;                                                                   
  15156. }                                                                               
  15157.                                                                                 
  15158. /****** Process article FIND command. ********************************/         
  15159.                                                                                 
  15160. static Bool                                                                     
  15161. article_find_command(np,gp,rest)                                                
  15162. Rstruc nncb         *np;                                                        
  15163. Rstruc newsgroup    *gp;                                                        
  15164. char                *rest;                                                      
  15165. {                                                                               
  15166.  struct newsarticle *save_top_article;                                          
  15167.  struct newsarticle *ap;                                                        
  15168.  struct newsarticle *found_article;                                             
  15169.  int                 findbump;                                                  
  15170.  Bool                string_given;                                              
  15171.  Bool                option_given;                                              
  15172.  char                string [ARGSIZE];                                          
  15173.  char                option [ARGSIZE];                                          
  15174.  struct countdown    cd;                                                        
  15175.                                                                                 
  15176.  if (!getop(np,&rest,&string,GETOP_LOWERCASE)) return FALSE;                    
  15177.  if (!getop(np,&rest,&option,GETOP_LOWERCASE)) return FALSE;                    
  15178.                                                                                 
  15179.  if (!getop(np,&rest,NULL,GETOP_NOMORE)) {                                      
  15180.    ERR1(                                                                        
  15181.     "Too many operands on the FIND command.  Try quoting the string.");         
  15182.    return FALSE;                                                                
  15183.  }                                                                              
  15184.                                                                                 
  15185.  string_given = *string;                                                        
  15186.  option_given = *option;                                                        
  15187.                                                                                 
  15188.  if (string_given) {                                                            
  15189.    strcpy(np->article_find_string,string);                                      
  15190.  }                                                                              
  15191.  else if (!*np->article_find_string) {                                          
  15192.    ERR1(                                                                        
  15193.       "The FIND command requires a string the first time it is used.");         
  15194.    return FALSE;                                                                
  15195.  }                                                                              
  15196.                                                                                 
  15197.  if (option_given) {                                                            
  15198.    if      (EQUAL(option,"next" )) np->article_find_option = FIND_NEXT;         
  15199.    else if (EQUAL(option,"first")) np->article_find_option = FIND_FIRST;        
  15200.    else if (EQUAL(option,"prev" )) np->article_find_option = FIND_PREV;         
  15201.    else if (EQUAL(option,"last" )) np->article_find_option = FIND_LAST;         
  15202.    else {                                                                       
  15203.      ERR1("Unknown FIND option.  Specify NEXT, PREV, FIRST or LAST.");          
  15204.      return FALSE;                                                              
  15205.    }                                                                            
  15206.  }                                                                              
  15207.  else {                                                                         
  15208.    if (string_given) np->article_find_option = FIND_NEXT;                       
  15209.    else switch (np->article_find_option) {                                      
  15210.      case FIND_NEXT:  np->article_find_option = FIND_NEXT; break;               
  15211.      case FIND_PREV:  np->article_find_option = FIND_PREV; break;               
  15212.      case FIND_FIRST: np->article_find_option = FIND_NEXT; break;               
  15213.      case FIND_LAST:  np->article_find_option = FIND_PREV; break;               
  15214.      default:         np->article_find_option = FIND_NEXT; break;               
  15215.    }                                                                            
  15216.  }                                                                              
  15217.                                                                                 
  15218.  np->article_repeat_find = !string_given;                                       
  15219.                                                                                 
  15220.  /* do the find here */                                                         
  15221.                                                                                 
  15222.  save_top_article = np->top_article;                                            
  15223.  switch (np->article_find_option) {                                             
  15224.    case FIND_NEXT:                                                              
  15225.                    findbump = 1;                                                
  15226.                    if (np->article_repeat_find) {                               
  15227.                      if (np->article_text_not_found)                            
  15228.                         np->top_article = gp->first_article;                    
  15229.                      else np->top_article++;                                    
  15230.                    }                                                            
  15231.                    break;                                                       
  15232.    case FIND_PREV:                                                              
  15233.                    findbump = -1;                                               
  15234.                    if (np->article_repeat_find) {                               
  15235.                      if (np->article_text_not_found)                            
  15236.                         np->top_article = gp->fake_last_article;                
  15237.                      else np->top_article--;                                    
  15238.                    }                                                            
  15239.                    break;                                                       
  15240.    case FIND_FIRST:                                                             
  15241.                    np->top_article = gp->first_article;                         
  15242.                    findbump = 1;                                                
  15243.                    break;                                                       
  15244.    case FIND_LAST:                                                              
  15245.                    np->top_article = gp->fake_last_article;                     
  15246.                    findbump = -1;                                               
  15247.                    break;                                                       
  15248.  }                                                                              
  15249.  if (!np->top_article) return FALSE;                                            
  15250.                                                                                 
  15251.  cd.do_update = (np->updatefreq >= 0);                                          
  15252.  cd.done      = 0;                                                              
  15253.  cd.to_do     = -1;                                                             
  15254.                                                                                 
  15255.  found_article = NULL;                                                          
  15256.  for (ap = np->top_article;                                                     
  15257.       ap <= gp->fake_last_article && ap >= gp->first_article;                   
  15258.       ap += findbump) {                                                         
  15259.    if (ArticleInTable(ap)                                                       
  15260.     && NNMrarh(np,gp,ap,FALSE,&cd)      /* Retrieve article header */           
  15261.     && NNMstrlc(ap->subject,np->article_find_string)) {                         
  15262.      found_article = ap;                                                        
  15263.      break;                                                                     
  15264.    }                                                                            
  15265.  }                                                                              
  15266.  if (!found_article) {                                                          
  15267.    np->top_article = save_top_article;                                          
  15268.    np->article_text_not_found = TRUE;                                           
  15269.    ERR3("No %s articles with subject of: '%s'",                                 
  15270.         (findbump > 0 ? "more" : "previous"),                                   
  15271.         np->article_find_string);                                               
  15272.  }                                                                              
  15273.  else {                                                                         
  15274.    np->top_article = found_article;                                             
  15275.    np->article_text_not_found = FALSE;                                          
  15276.    WARN1("Article found;\                                                       
  15277. The article whose subject contains the desired text tops the display.");        
  15278.  }                                                                              
  15279.                                                                                 
  15280.  return TRUE;                                                                   
  15281.                                                                                 
  15282. }                                                                               
  15283.                                                                                 
  15284. /****** Process article ONLY command. *******************************/          
  15285.                                                                                 
  15286. static Bool                                                                     
  15287. article_only_command(np,gp,rest)                                                
  15288. Rstruc nncb         *np;                                                        
  15289. Rstruc newsgroup    *gp;                                                        
  15290. char                *rest;                                                      
  15291. {                                                                               
  15292.  char                string[ARGSIZE];                                           
  15293.                                                                                 
  15294.  if (!getop(np,&rest,&string,GETOP_LOWERCASE)) return FALSE;                    
  15295.                                                                                 
  15296.  if (!getop(np,&rest,NULL,GETOP_NOMORE)) {                                      
  15297.    ERR1(                                                                        
  15298. "The ONLY command may have only one operand.  Try quoting the string."          
  15299.        );                                                                       
  15300.    return FALSE;                                                                
  15301.  }                                                                              
  15302.                                                                                 
  15303.  strcpy(np->article_only_string, string);                                       
  15304.                                                                                 
  15305.  np->article_criterion_changed = TRUE;                                          
  15306.  np->top_article = gp->first_article;                                           
  15307.  if (*np->article_only_string) {                                                
  15308.    WARN1(                                                                       
  15309. "To show articles with all subjects, use ONLY command with no operand."         
  15310.         );                                                                      
  15311.  }                                                                              
  15312.                                                                                 
  15313.  return TRUE;                                                                   
  15314. }                                                                               
  15315.                                                                                 
  15316. /****** Process article SORT command. *******************************/          
  15317.                                                                                 
  15318. static Bool                                                                     
  15319. article_sort_command(np,gp,rest)                                                
  15320. Rstruc nncb         *np;                                                        
  15321. Rstruc newsgroup    *gp;                                                        
  15322. char                *rest;                                                      
  15323. {                                                                               
  15324.  char                string[ARGSIZE];                                           
  15325.                                                                                 
  15326.  /* Usage: SORT Subject                                                         
  15327.   *        SORT Number                                                          
  15328.   */                                                                            
  15329.                                                                                 
  15330.  if (!getop(np,&rest,&string,GETOP_ASIS)) return FALSE;                         
  15331.                                                                                 
  15332.  if (!getop(np,&rest,NULL,GETOP_NOMORE)) {                                      
  15333.    ERR1("The SORT command requires one operand: Subject or Number.");           
  15334.    return FALSE;                                                                
  15335.  }                                                                              
  15336.                                                                                 
  15337.  switch (string[0]) {                                                           
  15338.    case 's':                                                                    
  15339.    case 'S': np->sort_by_subject = TRUE;  break;                                
  15340.    case 'n':                                                                    
  15341.    case 'N': np->sort_by_subject = FALSE; break;                                
  15342.    default:                                                                     
  15343.      ERR1("The SORT command requires one operand: Subject or Number.");         
  15344.      return FALSE;                                                              
  15345.  }                                                                              
  15346.                                                                                 
  15347.  if (np->sort_by_subject) retrieve_all_article_titles(np,gp);                   
  15348.                                                                                 
  15349.  NNMsort(np,gp);                                                                
  15350.                                                                                 
  15351.  np->article_criterion_changed = TRUE;                                          
  15352.  np->top_article = gp->first_article;                                           
  15353.                                                                                 
  15354.  return TRUE;                                                                   
  15355. }                                                                               
  15356.                                                                                 
  15357. /****** Process article EXTRACT command. *****************************/         
  15358.                                                                                 
  15359. static Bool                                                                     
  15360. article_extract_command(np,gp,rest)                                             
  15361. Rstruc nncb         *np;                                                        
  15362. Rstruc newsgroup    *gp;                                                        
  15363. char                *rest;                                                      
  15364. {                                                                               
  15365.  Bool                asked_for;                                                 
  15366.  char                nnchoice[2];                                               
  15367.                                                                                 
  15368.  if (!getop(np,&rest,NULL,GETOP_NOMORE)) {                                      
  15369.    ERR1("The EXTRACT command does not accept any operands.");                   
  15370.    return FALSE;                                                                
  15371.  }                                                                              
  15372.                                                                                 
  15373.  (void)NNMivput(np,"NNLGROUP ",gp->name,-1);                                    
  15374.                                                                                 
  15375.  /* Display panel asking whether it's list of titles or log of text */          
  15376.                                                                                 
  15377.  asked_for = TRUE;                                                              
  15378.                                                                                 
  15379.  (void)NNMispf(np,"ADDPOP");                                                    
  15380.  for (;;) {                                                                     
  15381.    if (NNMdispl(np,"NNMPEXNT") > 0) {                                           
  15382.      asked_for = FALSE;                                                         
  15383.      break;                                                                     
  15384.    }                                                                            
  15385.    (void)NNMivget(np,"NNCHOICE ",nnchoice,sizeof(nnchoice));                    
  15386.    if (*nnchoice == '?') {                                                      
  15387.      ERR1("Invalid choice;\                                                     
  15388. Move the cursor to a selection (or type S next to it) and press ENTER."         
  15389.          );                                                                     
  15390.    }                                                                            
  15391.    else break;                                                                  
  15392.  }                                                                              
  15393.                                                                                 
  15394.  (void)NNMispf(np,"REMPOP");                                                    
  15395.  if (!asked_for) return TRUE;                                                   
  15396.                                                                                 
  15397.  switch (*nnchoice) {                                                           
  15398.    case '1':  return NNMxartt(np,gp);                                           
  15399.    case '2':  return NNMxartx(np,gp,SEQ);                                       
  15400.    case '3':  return NNMxartx(np,gp,PDS);                                       
  15401.  }                                                                              
  15402.                                                                                 
  15403.  return FALSE;                                                                  
  15404. }                                                                               
  15405.                                                                                 
  15406. /****** Process article MARKALL command. *****************************/         
  15407.                                                                                 
  15408. static Bool                                                                     
  15409. article_markall_command(np,gp,rest)                                             
  15410. Rstruc nncb          *np;                                                       
  15411. Rstruc newsgroup     *gp;                                                       
  15412. char                 *rest;                                                     
  15413. {                                                                               
  15414.  Rstruc newsarticle  *ap;                                                       
  15415.  int                  prc;                                                      
  15416.  Bool                 allp;                                                     
  15417.  char                 nnchoice[9];                                              
  15418.                                                                                 
  15419.  if (!gp->first_article) {                                                      
  15420.    ERR1("There are no articles to mark.");                                      
  15421.    return TRUE;                                                                 
  15422.  }                                                                              
  15423.                                                                                 
  15424.  /* Display panel asking what user really wants to do. */                       
  15425.                                                                                 
  15426.  strcpy(nnchoice,"");                                                           
  15427.                                                                                 
  15428.  for (;;) {                                                                     
  15429.    (void)NNMivput(np,"NNMARK ","Read",-1);                                      
  15430.    (void)NNMispf(np,"ADDPOP");                                                  
  15431.    prc = NNMdispl(np,"NNMPMALL");                                               
  15432.    (void)NNMispf(np,"REMPOP");                                                  
  15433.    if (prc > 0) strcpy(nnchoice,"3");                                           
  15434.    else (void)NNMivget(np,"NNCHOICE ",nnchoice,sizeof(nnchoice));               
  15435.    switch (nnchoice[0]) {                                                       
  15436.      case '1': allp = TRUE;  break;                                             
  15437.      case '2': allp = FALSE; break;                                             
  15438.      case '3': ERR1("Operation cancelled by your request.");                    
  15439.                return TRUE;                                                     
  15440.      default:                                                                   
  15441.                 ERR1("Invalid choice;\                                          
  15442. Move the cursor to a selection (or type S next to it) and press ENTER."         
  15443.          );                                                                     
  15444.                 continue;                                                       
  15445.    }                                                                            
  15446.    break;                                                                       
  15447.  }                                                                              
  15448.                                                                                 
  15449.  if (allp) {                                                                    
  15450.    mark_all_articles_read(np,gp,FALSE);                                         
  15451.    for (ap = gp->first_article; ap <= gp->real_last_article; ap++) {            
  15452.      ap->action = READ;                                                         
  15453.    }                                                                            
  15454.  }                                                                              
  15455.  else {                                                                         
  15456.    for (ap = gp->first_article; ap <= gp->real_last_article; ap++) {            
  15457.      if (ArticleInTable(ap)) {                                                  
  15458.        NNMmarr(np,gp,ap);                                                       
  15459.      }                                                                          
  15460.    }                                                                            
  15461.  }                                                                              
  15462.                                                                                 
  15463.  return TRUE;                                                                   
  15464. }                                                                               
  15465.                                                                                 
  15466. /****** Process article UNMARKALL command. ***************************/         
  15467.                                                                                 
  15468. static Bool                                                                     
  15469. article_unmarkall_command(np,gp,rest)                                           
  15470. Rstruc nncb          *np;                                                       
  15471. Rstruc newsgroup     *gp;                                                       
  15472. char                 *rest;                                                     
  15473. {                                                                               
  15474.  Rstruc newsarticle  *ap;                                                       
  15475.  int                  prc;                                                      
  15476.  Bool                 allp;                                                     
  15477.  char                 nnchoice[9];                                              
  15478.                                                                                 
  15479.  if (!gp->first_article) {                                                      
  15480.    ERR1("There are no articles to mark.");                                      
  15481.    return TRUE;                                                                 
  15482.  }                                                                              
  15483.                                                                                 
  15484.  /* Display panel asking what user really wants to do. */                       
  15485.                                                                                 
  15486.  strcpy(nnchoice,"");                                                           
  15487.                                                                                 
  15488.  for (;;) {                                                                     
  15489.    (void)NNMivput(np,"NNMARK ","Unread",-1);                                    
  15490.    (void)NNMispf(np,"ADDPOP");                                                  
  15491.    prc = NNMdispl(np,"NNMPMALL");                                               
  15492.    (void)NNMispf(np,"REMPOP");                                                  
  15493.    if (prc > 0) strcpy(nnchoice,"3");                                           
  15494.    else (void)NNMivget(np,"NNCHOICE ",nnchoice,sizeof(nnchoice));               
  15495.    switch (nnchoice[0]) {                                                       
  15496.      case '1': allp = TRUE;  break;                                             
  15497.      case '2': allp = FALSE; break;                                             
  15498.      case '3': ERR1("Operation cancelled by your request.");                    
  15499.                return TRUE;                                                     
  15500.      default:                                                                   
  15501.                 ERR1("Invalid choice;\                                          
  15502. Move the cursor to a selection (or type S next to it) and press ENTER."         
  15503.          );                                                                     
  15504.                 continue;                                                       
  15505.    }                                                                            
  15506.    break;                                                                       
  15507.  }                                                                              
  15508.                                                                                 
  15509.  if (allp) {                                                                    
  15510.    mark_all_articles_unread(np,gp,FALSE);                                       
  15511.    for (ap = gp->first_article; ap <= gp->real_last_article; ap++) {            
  15512.      ap->action = UNREAD;                                                       
  15513.    }                                                                            
  15514.  }                                                                              
  15515.  else {                                                                         
  15516.    for (ap = gp->first_article; ap <= gp->real_last_article; ap++) {            
  15517.      if (ArticleInTable(ap)) {                                                  
  15518.        NNMmaru(np,gp,ap);                                                       
  15519.      }                                                                          
  15520.    }                                                                            
  15521.  }                                                                              
  15522.                                                                                 
  15523.  return TRUE;                                                                   
  15524. }                                                                               
  15525.                                                                                 
  15526. /****** Process article TITLES command. ******************************/         
  15527.                                                                                 
  15528. static Bool                                                                     
  15529. article_titles_command(np,gp,rest)                                              
  15530. Rstruc nncb         *np;                                                        
  15531. Rstruc newsgroup    *gp;                                                        
  15532. char                *rest;                                                      
  15533. {                                                                               
  15534.                                                                                 
  15535.  /* Actually, this probably ought to be a NOP, since we always ought to         
  15536.   * be retrieving article titles as we display a screenful.                     
  15537.   * Since this command retrieves ALL titles, it's kind of wasteful.             
  15538.   */                                                                            
  15539.                                                                                 
  15540.  retrieve_all_article_titles(np,gp);                                            
  15541.                                                                                 
  15542.  return TRUE;                                                                   
  15543.                                                                                 
  15544. }                                                                               
  15545.                                                                                 
  15546. /****** Process article QUERY command. *******************************/         
  15547.                                                                                 
  15548. static Bool                                                                     
  15549. article_query_command(np,gp,rest)                                               
  15550. Rstruc nncb         *np;                                                        
  15551. Rstruc newsgroup    *gp;                                                        
  15552. char                *rest;                                                      
  15553. {                                                                               
  15554.                                                                                 
  15555.  NNMqng(np,gp);                          /* Query newsgroup */                  
  15556.                                                                                 
  15557.  return TRUE;                                                                   
  15558. }                                                                               
  15559.                                                                                 
  15560. /****** Process POST command. ****************************************/         
  15561.                                                                                 
  15562. static Bool                                                                     
  15563. general_post_command(np,gp,rest)                                                
  15564. Rstruc nncb         *np;                                                        
  15565. Rstruc newsgroup    *gp;                                                        
  15566. char                *rest;                                                      
  15567. {                                                                               
  15568.                                                                                 
  15569.  NNMdpost(np,gp,NULL);      /* Do posting (no article up to follow) */          
  15570.                                                                                 
  15571.  return TRUE;                                                                   
  15572. }                                                                               
  15573.                                                                                 
  15574. /****** Process MAIL command. ****************************************/         
  15575.                                                                                 
  15576. static Bool                                                                     
  15577. general_mail_command(np,gp,rest)                                                
  15578. Rstruc nncb         *np;                                                        
  15579. Rstruc newsgroup    *gp;                                                        
  15580. char                *rest;                                                      
  15581. {                                                                               
  15582.                                                                                 
  15583.  NNMdmail(np,gp,NULL);      /* Do mailing (no article to to reply) */           
  15584.                                                                                 
  15585.  return TRUE;                                                                   
  15586. }                                                                               
  15587.                                                                                 
  15588. /****** Process TEST command. ****************************************/         
  15589.                                                                                 
  15590. static Bool                                                                     
  15591. general_test_command(np,gp,rest)                                                
  15592. Rstruc nncb         *np;                                                        
  15593. struct newsgroup    *gp;                                                        
  15594. char                *rest;                                                      
  15595. {                                                                               
  15596.                                                                                 
  15597.  np->test_mode = TRUE;                                                          
  15598.  __ctest(rest);                                                                 
  15599.                                                                                 
  15600.  return TRUE;                                                                   
  15601. }                                                                               
  15602.                                                                                 
  15603. /****** Process NNTP command. ****************************************/         
  15604.                                                                                 
  15605. static Bool                                                                     
  15606. general_nntp_command(np,gp,rest)                                                
  15607. Rstruc nncb         *np;                                                        
  15608. struct newsgroup    *gp;                                                        
  15609. char                *rest;                                                      
  15610. {                                                                               
  15611.                                                                                 
  15612.  (void)NNMdnntp(np,rest);      /* Do native NNTP */                             
  15613.                                                                                 
  15614.  return TRUE;                                                                   
  15615. }                                                                               
  15616.                                                                                 
  15617. /****** Process SAVE command. ****************************************/         
  15618.                                                                                 
  15619. static Bool                                                                     
  15620. general_save_command(np,gp,rest)                                                
  15621. Rstruc nncb         *np;                                                        
  15622. struct newsgroup    *gp;                                                        
  15623. char                *rest;                                                      
  15624. {                                                                               
  15625.                                                                                 
  15626.  return NNMsave(np,rest);  /* Save NEWSRC file */                               
  15627.                                                                                 
  15628. }                                                                               
  15629.                                                                                 
  15630. /****** Process OPTIONS command. *************************************/         
  15631.                                                                                 
  15632. static Bool                                                                     
  15633. general_options_command(np,gp,rest)                                             
  15634. Rstruc nncb         *np;                                                        
  15635. struct newsgroup    *gp;                                                        
  15636. char                *rest;                                                      
  15637. {                                                                               
  15638.  char                option[ARGSIZE];                                           
  15639.                                                                                 
  15640.  if (!getop(np,&rest,&option,GETOP_LOWERCASE)) return FALSE;                    
  15641.                                                                                 
  15642.  NNMdsopt(np,option);         /* Do "set options" function */                   
  15643.                                                                                 
  15644.  return TRUE;                                                                   
  15645. }                                                                               
  15646.                                                                                 
  15647. /****** Process QUIT command. ****************************************/         
  15648.                                                                                 
  15649. static Bool                                                                     
  15650. general_quit_command(np,gp,rest)                                                
  15651. Rstruc nncb         *np;                                                        
  15652. struct newsgroup    *gp;                                                        
  15653. char                *rest;                                                      
  15654. {                                                                               
  15655.                                                                                 
  15656.  np->quit = TRUE;                                                               
  15657.                                                                                 
  15658.  return TRUE;                                                                   
  15659. }                                                                               
  15660.                                                                                 
  15661. /****** Process newsgroup S selection. *******************************/         
  15662.                                                                                 
  15663. static Bool                                                                     
  15664. newsgroup_s_selection(np,gp)                                                    
  15665. Rstruc nncb          *np;                                                       
  15666. Rstruc newsgroup     *gp;                                                       
  15667. {                                                                               
  15668.                                                                                 
  15669.  np->show_all_articles       = FALSE;                                           
  15670.  np->bypass_header_retrieval = FALSE;                                           
  15671.  np->unread_articles_only    = FALSE;                                           
  15672.                                                                                 
  15673.  return(NNMpng(np,gp));                            /* Pick newsgroup */         
  15674.                                                                                 
  15675. }                                                                               
  15676.                                                                                 
  15677. /****** Process newsgroup N selection. *******************************/         
  15678.                                                                                 
  15679. static Bool                                                                     
  15680. newsgroup_n_selection(np,gp)                                                    
  15681. Rstruc nncb          *np;                                                       
  15682. Rstruc newsgroup     *gp;                                                       
  15683. {                                                                               
  15684.                                                                                 
  15685.  np->show_all_articles       = FALSE;                                           
  15686.  np->bypass_header_retrieval = FALSE;                                           
  15687.  np->unread_articles_only    = TRUE;                                            
  15688.                                                                                 
  15689.  return(NNMpng(np,gp));                            /* Pick newsgroup */         
  15690.                                                                                 
  15691. }                                                                               
  15692.                                                                                 
  15693. /****** Process newsgroup A selection. *******************************/         
  15694.                                                                                 
  15695. static Bool                                                                     
  15696. newsgroup_a_selection(np,gp)                                                    
  15697. Rstruc nncb          *np;                                                       
  15698. Rstruc newsgroup     *gp;                                                       
  15699. {                                                                               
  15700.                                                                                 
  15701.  np->show_all_articles       = TRUE;                                            
  15702.  np->bypass_header_retrieval = FALSE;                                           
  15703.  np->unread_articles_only    = FALSE;                                           
  15704.                                                                                 
  15705.  return(NNMpng(np,gp));                            /* Pick newsgroup */         
  15706.                                                                                 
  15707. }                                                                               
  15708.                                                                                 
  15709. /****** Process newsgroup Z selection. *******************************/         
  15710.                                                                                 
  15711. static Bool                                                                     
  15712. newsgroup_z_selection(np,gp)                                                    
  15713. Rstruc nncb          *np;                                                       
  15714. Rstruc newsgroup     *gp;                                                       
  15715. {                                                                               
  15716.                                                                                 
  15717.  np->show_all_articles       = TRUE;                                            
  15718.  np->bypass_header_retrieval = TRUE;                                            
  15719.  np->unread_articles_only    = FALSE;                                           
  15720.                                                                                 
  15721.  return(NNMpng(np,gp));                            /* Pick newsgroup */         
  15722.                                                                                 
  15723. }                                                                               
  15724.                                                                                 
  15725. /****** Process newsgroup Q selection. *******************************/         
  15726.                                                                                 
  15727. static Bool                                                                     
  15728. newsgroup_q_selection(np,gp)                                                    
  15729. Rstruc nncb         *np;                                                        
  15730. Rstruc newsgroup    *gp;                                                        
  15731. {                                                                               
  15732.                                                                                 
  15733.  NNMqng(np,gp);                          /* Query newsgroup */                  
  15734.                                                                                 
  15735.  return TRUE;                                                                   
  15736. }                                                                               
  15737.                                                                                 
  15738. /****** Process newsgroup R selection. *******************************/         
  15739.                                                                                 
  15740. static Bool                                                                     
  15741. newsgroup_r_selection(np,gp)                                                    
  15742. Rstruc nncb          *np;                                                       
  15743. Rstruc newsgroup     *gp;                                                       
  15744. {                                                                               
  15745.                                                                                 
  15746.  gp->registered = 1;                                                            
  15747.                                                                                 
  15748.  WARN2("Newsgroup %s registered (subscribed).", gp->name);                      
  15749.                                                                                 
  15750.  return TRUE;                                                                   
  15751. }                                                                               
  15752.                                                                                 
  15753. /****** Process newsgroup D selection. *******************************/         
  15754.                                                                                 
  15755. static Bool                                                                     
  15756. newsgroup_d_selection(np,gp)                                                    
  15757. Rstruc nncb          *np;                                                       
  15758. Rstruc newsgroup     *gp;                                                       
  15759. {                                                                               
  15760.                                                                                 
  15761.  gp->registered = 0;                                                            
  15762.                                                                                 
  15763.  WARN2("Newsgroup %s deregistered (unsubscribed).", gp->name);                  
  15764.                                                                                 
  15765.  return TRUE;                                                                   
  15766. }                                                                               
  15767.                                                                                 
  15768. /****** Process newsgroup M selection. *******************************/         
  15769.                                                                                 
  15770. static Bool                                                                     
  15771. newsgroup_m_selection(np,gp)                                                    
  15772. Rstruc nncb          *np;                                                       
  15773. Rstruc newsgroup     *gp;                                                       
  15774. {                                                                               
  15775.                                                                                 
  15776.  return mark_all_articles_read(np,gp,TRUE);                                     
  15777.                                                                                 
  15778. }                                                                               
  15779.                                                                                 
  15780. /****** Process newsgroup U selection. *******************************/         
  15781.                                                                                 
  15782. static Bool                                                                     
  15783. newsgroup_u_selection(np,gp)                                                    
  15784. Rstruc nncb          *np;                                                       
  15785. Rstruc newsgroup     *gp;                                                       
  15786. {                                                                               
  15787.                                                                                 
  15788.  return mark_all_articles_unread(np,gp,TRUE);                                   
  15789.                                                                                 
  15790. }                                                                               
  15791.                                                                                 
  15792. /****** Process article E selection. *********************************/         
  15793.                                                                                 
  15794. static Bool                                                                     
  15795. article_e_selection(np,ap)                                                      
  15796. Rstruc nncb          *np;                                                       
  15797. Rstruc newsarticle   *ap;                                                       
  15798. {                                                                               
  15799.                                                                                 
  15800.  np->extract_file = NULL;                                                       
  15801.  if (!NNMpick(np,ap)) return FALSE;                                             
  15802.  NNMdoit(np,ap,'E');                                                            
  15803.  return TRUE;                                                                   
  15804.                                                                                 
  15805. }                                                                               
  15806.                                                                                 
  15807. /****** Process article F selection. *********************************/         
  15808.                                                                                 
  15809. static Bool                                                                     
  15810. article_f_selection(np,ap)                                                      
  15811. Rstruc nncb          *np;                                                       
  15812. Rstruc newsarticle   *ap;                                                       
  15813. {                                                                               
  15814.                                                                                 
  15815.  if (!NNMpick(np,ap)) return FALSE;                                             
  15816.  NNMdoit(np,ap,'F');                                                            
  15817.  return TRUE;                                                                   
  15818.                                                                                 
  15819. }                                                                               
  15820.                                                                                 
  15821. /****** Process article C selection. *********************************/         
  15822.                                                                                 
  15823. static Bool                                                                     
  15824. article_c_selection(np,ap)                                                      
  15825. Rstruc nncb          *np;                                                       
  15826. Rstruc newsarticle   *ap;                                                       
  15827. {                                                                               
  15828.                                                                                 
  15829.  if (!NNMpick(np,ap)) return FALSE;                                             
  15830.  NNMdoit(np,ap,'C');                                                            
  15831.  return TRUE;                                                                   
  15832.                                                                                 
  15833. }                                                                               
  15834.                                                                                 
  15835. /****** Process article M selection. *********************************/         
  15836.                                                                                 
  15837. static Bool                                                                     
  15838. article_m_selection(np,ap)                                                      
  15839. Rstruc nncb         *np;                                                        
  15840. Rstruc newsarticle  *ap;                                                        
  15841. {                                                                               
  15842.  Rstruc newsgroup   *gp;                                                        
  15843.                                                                                 
  15844.  gp = np->current_newsgroup;                                                    
  15845.                                                                                 
  15846.  if (!gp) {                                                                     
  15847.   CRIT1("No current newsgroup.  This should never happen.");                    
  15848.   return FALSE;                                                                 
  15849.  }                                                                              
  15850.                                                                                 
  15851.  NNMmarr(np,gp,ap);                          /* Make article read */            
  15852.                                                                                 
  15853.  return TRUE;                                                                   
  15854. }                                                                               
  15855.                                                                                 
  15856. /****** Process article P selection. *********************************/         
  15857.                                                                                 
  15858. static Bool                                                                     
  15859. article_p_selection(np,ap)                                                      
  15860. Rstruc nncb          *np;                                                       
  15861. Rstruc newsarticle   *ap;                                                       
  15862. {                                                                               
  15863.                                                                                 
  15864.  if (!NNMpick(np,ap)) return FALSE;                                             
  15865.  NNMdoit(np,ap,'P');                                                            
  15866.  return TRUE;                                                                   
  15867.                                                                                 
  15868. }                                                                               
  15869.                                                                                 
  15870. /****** Process article Q selection. *********************************/         
  15871.                                                                                 
  15872. static Bool                                                                     
  15873. article_q_selection(np,ap)                                                      
  15874. Rstruc nncb         *np;                                                        
  15875. Rstruc newsarticle  *ap;                                                        
  15876. {                                                                               
  15877.                                                                                 
  15878.  return NNMqar(np,ap);                                                          
  15879. }                                                                               
  15880.                                                                                 
  15881. /****** Process article R selection. *********************************/         
  15882.                                                                                 
  15883. static Bool                                                                     
  15884. article_r_selection(np,ap)                                                      
  15885. Rstruc nncb          *np;                                                       
  15886. Rstruc newsarticle   *ap;                                                       
  15887. {                                                                               
  15888.                                                                                 
  15889.  if (!NNMpick(np,ap)) return FALSE;                                             
  15890.  NNMdoit(np,ap,'R');                                                            
  15891.  return TRUE;                                                                   
  15892.                                                                                 
  15893. }                                                                               
  15894.                                                                                 
  15895. /****** Process article S selection. *********************************/         
  15896.                                                                                 
  15897. static Bool                                                                     
  15898. article_s_selection(np,ap)                                                      
  15899. Rstruc nncb          *np;                                                       
  15900. Rstruc newsarticle   *ap;                                                       
  15901. {                                                                               
  15902.  Rstruc newsgroup    *gp = np->current_newsgroup;                               
  15903.  Rstruc newsarticle  *ap1;                                                      
  15904.  Rstruc newsarticle  *ap2;                                                      
  15905.  Rstruc newsarticle  *ap3;                                                      
  15906.  char                *subj;                                                     
  15907.  int                 cookie;                                                    
  15908.  struct countdown    cd;                                                        
  15909.                                                                                 
  15910.  ap1 = ap;                                                                      
  15911.  np->extract_file = NULL;                                                       
  15912.  if (!NNMpick(np,ap1)) return FALSE;  /* Pick article to process */             
  15913.  NNMdoit(np,ap1,'S');                 /* Process article */                     
  15914.                                                                                 
  15915.  /* Continue as long as NEXT/PREV/UNREAD requests occur. */                     
  15916.                                                                                 
  15917.  cd.do_update = (np->updatefreq >= 0);                                          
  15918.  cd.done      = 0;                                                              
  15919.  cd.to_do     = -1;                                                             
  15920.                                                                                 
  15921.  clear_subject(np);                                                             
  15922.                                                                                 
  15923.  while ((ap2=np->another_article)) {                                            
  15924.    switch ((cookie=(int)ap2)) {                                                 
  15925.      case UNREAD_THIS_ARTICLE:                                                  
  15926.           clear_subject(np);                                                    
  15927.           NNMmaru(np,gp,ap1);            /* Make article unread */              
  15928.           return TRUE;                                                          
  15929.      case NEXT_THREAD_ARTICLE:                                                  
  15930.           subj = set_subject(np,ap1);                                           
  15931.           for (ap2=ap1+1; ap2 <= gp->real_last_article; ap2++) {                
  15932.             if ((ArticleInTable(ap2) || np->show_all_articles)                  
  15933.               && NNMrarh(np,gp,ap2,FALSE,&cd)) { /* retrieve art hdr */         
  15934.               if (NNMsumat(subj,ap2->subject))   /* if subject match */         
  15935.                   break;                                                        
  15936.             }                                                                   
  15937.           }                                                                     
  15938.           if (ap2 > gp->real_last_article) {                                    
  15939.             if (np->show_all_articles) ERR1(                                    
  15940.    "There are no further articles on this subject in this newsgroup.");         
  15941.             else ERR1(                                                          
  15942.    "No further UNREAD articles on this subject in this newsgroup.");            
  15943.             clear_subject(np);                                                  
  15944.             ap2 = ap1;    /* go back to article you were in */                  
  15945.           }                                                                     
  15946.           break;                                                                
  15947.      case PREV_THREAD_ARTICLE:                                                  
  15948.           subj = set_subject(np,ap1);                                           
  15949.           for (ap2=ap1-1; ap2 >= gp->first_article; ap2--) {                    
  15950.             if ((ArticleInTable(ap2) || np->show_all_articles)                  
  15951.               && NNMrarh(np,gp,ap2,FALSE,&cd)) { /* retrieve art hdr */         
  15952.               if (NNMsumat(subj,ap2->subject))   /* if subject match */         
  15953.                   break;                                                        
  15954.             }                                                                   
  15955.           }                                                                     
  15956.           if (ap2 < gp->first_article) {                                        
  15957.             if (np->show_all_articles) ERR1(                                    
  15958.   "There are no previous articles on this subject in this newsgroup.");         
  15959.             else ERR1(                                                          
  15960.   "No previous UNREAD articles on this subject in this newsgroup.");            
  15961.             clear_subject(np);                                                  
  15962.             ap2 = ap1;    /* go back to article you were in */                  
  15963.           }                                                                     
  15964.           break;                                                                
  15965.      case FIRST_THREAD_ARTICLE:                                                 
  15966.           subj = set_subject(np,ap1);                                           
  15967.           for (ap2=gp->first_article;                                           
  15968.                ap2 <= gp->real_last_article; ap2++) {                           
  15969.             if ((ArticleInTable(ap2) || np->show_all_articles)                  
  15970.               && NNMrarh(np,gp,ap2,FALSE,&cd)) { /* retrieve art hdr */         
  15971.               if (NNMsumat(subj,ap2->subject))   /* if subject match */         
  15972.                   break;                                                        
  15973.             }                                                                   
  15974.           }                                                                     
  15975.           if (ap2 > gp->real_last_article) {                                    
  15976.             if (np->show_all_articles) ERR1(                                    
  15977. "No other article could be found on this subject in this newsgroup.");          
  15978.             else                       ERR1(                                    
  15979. "No UNREAD article could be found on this subject in this newsgroup.");         
  15980.             clear_subject(np);                                                  
  15981.             ap2 = ap1;    /* go back to article you were in */                  
  15982.           }                                                                     
  15983.           break;                                                                
  15984.      case LAST_THREAD_ARTICLE:                                                  
  15985.           subj = set_subject(np,ap1);                                           
  15986.           for (ap2=gp->real_last_article;                                       
  15987.                ap2 >= gp->first_article; ap2--) {                               
  15988.             if ((ArticleInTable(ap2) || np->show_all_articles)                  
  15989.               && NNMrarh(np,gp,ap2,FALSE,&cd)) { /* retrieve art hdr */         
  15990.               if (NNMsumat(subj,ap2->subject))   /* if subject match */         
  15991.                   break;                                                        
  15992.             }                                                                   
  15993.           }                                                                     
  15994.           if (ap2 < gp->first_article) {                                        
  15995.             if (np->show_all_articles) ERR1(                                    
  15996. "No other article could be found on this subject in this newsgroup.");          
  15997.             else                       ERR1(                                    
  15998. "No UNREAD article could be found on this subject in this newsgroup.");         
  15999.             clear_subject(np);                                                  
  16000.             ap2 = ap1;    /* go back to article you were in */                  
  16001.           }                                                                     
  16002.           break;                                                                
  16003.      case NEW_THREAD_ARTICLE:                                                   
  16004.           subj = set_subject(np,ap1);                                           
  16005.           for (ap2=gp->first_article;                                           
  16006.                ap2 <= gp->real_last_article; ap2++) {                           
  16007.             if (V_STATUS(gp,ap2->number) == V_UNREAD                            
  16008.                 && !NNMsumat(subj,ap2->subject)) /* subject nomatch */          
  16009.                break;                                                           
  16010.           }                                                                     
  16011.           clear_subject(np);                                                    
  16012.           if (ap2 > gp->real_last_article) {                                    
  16013.             ERR1(                                                               
  16014.   "There are no unread articles on other subjects in this newsgroup.");         
  16015.             ap2 = ap1;    /* go back to article you were in */                  
  16016.           }                                                                     
  16017.           else (void)set_subject(np,ap2);                                       
  16018.           break;                                                                
  16019.                                                                                 
  16020.   /* Otherwise NEXT, PREV or misc. command from browse.                         
  16021.    * Note that misc. commands act like "re-go to current article"               
  16022.    * to force redisplay.                                                        
  16023.    */                                                                           
  16024.                                                                                 
  16025.     default:                                                                    
  16026.           clear_subject(np);                                                    
  16027.           break;                                                                
  16028.    }                                                                            
  16029.                                                                                 
  16030.    np->top_article = ap2;  /* Bump display to article to be seen */             
  16031.    SetArticleInTable(ap2); /* Force it eligible for display */                  
  16032.    ap1 = ap2;                                                                   
  16033.    if (!NNMpick(np,ap1)) return FALSE;  /* Pick article to process */           
  16034.    NNMdoit(np,ap1,'S');                 /* Process article */                   
  16035.  }                                                                              
  16036.                                                                                 
  16037.  clear_subject(np);                                                             
  16038.                                                                                 
  16039.  return TRUE;                                                                   
  16040.                                                                                 
  16041. }                                                                               
  16042.                                                                                 
  16043. /****** Process article U selection. *********************************/         
  16044.                                                                                 
  16045. static Bool                                                                     
  16046. article_u_selection(np,ap)                                                      
  16047. Rstruc nncb         *np;                                                        
  16048. Rstruc newsarticle  *ap;                                                        
  16049. {                                                                               
  16050.  Rstruc newsgroup   *gp;                                                        
  16051.                                                                                 
  16052.  gp = np->current_newsgroup;                                                    
  16053.                                                                                 
  16054.  if (gp == NULL) {                                                              
  16055.   CRIT1("No current newsgroup.  This should never happen.");                    
  16056.   return FALSE;                                                                 
  16057.  }                                                                              
  16058.                                                                                 
  16059.  NNMmaru(np,gp,ap);                         /* Make article unread */           
  16060.                                                                                 
  16061.  return TRUE;                                                                   
  16062. }                                                                               
  16063.                                                                                 
  16064. /*********************************************************************/         
  16065.                                                                                 
  16066. void                                                                            
  16067. NNMinit(np)                                                                     
  16068. Rstruc nncb            *np;                                                     
  16069. {                                                                               
  16070.                                                                                 
  16071.  static struct tabledesc newsgroup_display_table;                               
  16072.  static struct tabledesc article_display_table;                                 
  16073.  static struct cmddesc   newsgroup_commands[] = {                               
  16074.                           {"L          ",newsgroup_locate_command   },          
  16075.                           {"LOC        ",newsgroup_locate_command   },          
  16076.                           {"LOCATE     ",newsgroup_locate_command   },          
  16077.                           {"F          ",newsgroup_find_command     },          
  16078.                           {"FIND       ",newsgroup_find_command     },          
  16079.                           {"EXT        ",newsgroup_extract_command  },          
  16080.                           {"EXTRACT    ",newsgroup_extract_command  },          
  16081.                           {"REG        ",newsgroup_reg_command      },          
  16082.                           {"REGISTER   ",newsgroup_reg_command      },          
  16083.                           {"ALL        ",newsgroup_all_command      },          
  16084.                           {"ONLY       ",newsgroup_only_command     },          
  16085.                           {"ORDER      ",newsgroup_order_command    },          
  16086.                           {"POST       ",general_post_command       },          
  16087.                           {"MAIL       ",general_mail_command       },          
  16088.                           {"TEST       ",general_test_command       },          
  16089.                           {"NNTP       ",general_nntp_command       },          
  16090.                           {"SAVE       ",general_save_command       },          
  16091.                           {"OPTIONS    ",general_options_command    },          
  16092.                           {"OPT        ",general_options_command    },          
  16093.                           {"QUIT       ",general_quit_command       },          
  16094.                           {"           ",NULL}                                  
  16095.                          };                                                     
  16096.  static struct cmddesc   article_commands[] = {                                 
  16097.                           {"L          ",article_locate_command     },          
  16098.                           {"LOC        ",article_locate_command     },          
  16099.                           {"LOCATE     ",article_locate_command     },          
  16100.                           {"F          ",article_find_command       },          
  16101.                           {"FIND       ",article_find_command       },          
  16102.                           {"EXT        ",article_extract_command    },          
  16103.                           {"EXTRACT    ",article_extract_command    },          
  16104.                           {"MARKALL    ",article_markall_command    },          
  16105.                           {"UNMARKALL  ",article_unmarkall_command  },          
  16106.                           {"TITLE      ",article_titles_command     },          
  16107.                           {"TITLES     ",article_titles_command     },          
  16108.                           {"ONLY       ",article_only_command       },          
  16109.                           {"Q          ",article_query_command      },          
  16110.                           {"QUERY      ",article_query_command      },          
  16111.                           {"SORT       ",article_sort_command       },          
  16112.                           {"POST       ",general_post_command       },          
  16113.                           {"MAIL       ",general_mail_command       },          
  16114.                           {"TEST       ",general_test_command       },          
  16115.                           {"NNTP       ",general_nntp_command       },          
  16116.                           {"SAVE       ",general_save_command       },          
  16117.                           {"OPTIONS    ",general_options_command    },          
  16118.                           {"OPT        ",general_options_command    },          
  16119.                           {"QUIT       ",general_quit_command       },          
  16120.                           {"           ",NULL}                                  
  16121.                          };                                                     
  16122.  static struct seldesc   newsgroup_selections[] = {                             
  16123.                           {'S',newsgroup_s_selection },                         
  16124.                           {'N',newsgroup_n_selection },                         
  16125.                           {'A',newsgroup_a_selection },                         
  16126.                           {'R',newsgroup_r_selection },                         
  16127.                           {'D',newsgroup_d_selection },                         
  16128.                           {'M',newsgroup_m_selection },                         
  16129.                           {'U',newsgroup_u_selection },                         
  16130.                           {'Q',newsgroup_q_selection },                         
  16131.                           {'Z',newsgroup_z_selection },                         
  16132.                           {' ',NULL}                                            
  16133.                          };                                                     
  16134.  static struct seldesc   article_selections[] = {                               
  16135.                           {'S',article_s_selection },                           
  16136.                           {'E',article_e_selection },                           
  16137.                           {'M',article_m_selection },                           
  16138.                           {'U',article_u_selection },                           
  16139.                           {'F',article_f_selection },                           
  16140.                           {'R',article_r_selection },                           
  16141.                        /* {'P',article_p_selection }, */                        
  16142.                           {'Q',article_q_selection },                           
  16143.                           {'C',article_c_selection },                           
  16144.                           {' ',NULL}                                            
  16145.                          };                                                     
  16146.                                                                                 
  16147.  newsgroup_display_table.command_variable   = "NNGCMD ";                        
  16148.  newsgroup_display_table.first_cmddesc      = newsgroup_commands;               
  16149.  newsgroup_display_table.first_seldesc      = newsgroup_selections;             
  16150.                                                                                 
  16151.  article_display_table.command_variable     = "NNTCMD ";                        
  16152.  article_display_table.first_cmddesc        = article_commands;                 
  16153.  article_display_table.first_seldesc        = article_selections;               
  16154.                                                                                 
  16155.  np->newsgroup_display_table_address = &newsgroup_display_table;                
  16156.  np->article_display_table_address   = &article_display_table;                  
  16157.                                                                                 
  16158.  return;                                                                        
  16159. }                                                                               
  16160.                                                                                 
  16161. ./   ADD NAME=NNMISPF,SSI=01050056                                              
  16162.                                                                                 
  16163.  /********************************************************************/         
  16164.  /*                                                                  */         
  16165.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  16166.  /*                                                                  */         
  16167.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  16168.  /* including the implied warranties of merchantability and fitness, */         
  16169.  /* are expressly denied.                                            */         
  16170.  /*                                                                  */         
  16171.  /* Provided this copyright notice is included, this software may    */         
  16172.  /* be freely distributed and not offered for sale.                  */         
  16173.  /*                                                                  */         
  16174.  /* Changes or modifications may be made and used only by the maker  */         
  16175.  /* of same, and not further distributed.  Such modifications should */         
  16176.  /* be mailed to the author for consideration for addition to the    */         
  16177.  /* software and incorporation in subsequent releases.               */         
  16178.  /*                                                                  */         
  16179.  /********************************************************************/         
  16180.                                                                                 
  16181. #pragma  csect(code,  "NN@ISPF ")                                               
  16182. #pragma  csect(static,"NN$ISPF ")                                               
  16183. #include "nn.h"                                                                 
  16184.                                                                                 
  16185. /****** Call ISPF service. *******************************************/         
  16186.                                                                                 
  16187. Bool                                                                            
  16188. NNMispf(np,ispfbuf)                                                             
  16189. Rstruc nncb *np;                                                                
  16190. char        *ispfbuf;                                                           
  16191. {                                                                               
  16192.  int         ispflen;                                                           
  16193.                                                                                 
  16194.  ispflen = strlen(ispfbuf);                                                     
  16195.  np->ispfrc = ISPEXEC(&ispflen,ispfbuf);                                        
  16196.  if (np->ispfrc > 8) {                                                          
  16197.                                                                                 
  16198.    /* Ignore ADDPOP and REMPOP errors, especially if they are due to            
  16199.       ISPF V3 not being active. */                                              
  16200.                                                                                 
  16201.    if (np->ispfrc == 20                                                         
  16202.     && np->debug_mode == FALSE                                                  
  16203.     && ispflen > 6                                                              
  16204.     && (memcmp(ispfbuf,"ADDPOP",6) == 0                                         
  16205.      || memcmp(ispfbuf,"REMPOP",6) == 0)) {                                     
  16206.      return TRUE;                                                               
  16207.    }                                                                            
  16208.                                                                                 
  16209.    NNMierr(np);             /* handle ISPF error */                             
  16210.    return FALSE;                                                                
  16211.  }                                                                              
  16212.  return TRUE;                                                                   
  16213. }                                                                               
  16214.                                                                                 
  16215. ./   ADD NAME=NNMIVGET,SSI=01030016                                             
  16216.                                                                                 
  16217.  /********************************************************************/         
  16218.  /*                                                                  */         
  16219.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  16220.  /*                                                                  */         
  16221.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  16222.  /* including the implied warranties of merchantability and fitness, */         
  16223.  /* are expressly denied.                                            */         
  16224.  /*                                                                  */         
  16225.  /* Provided this copyright notice is included, this software may    */         
  16226.  /* be freely distributed and not offered for sale.                  */         
  16227.  /*                                                                  */         
  16228.  /* Changes or modifications may be made and used only by the maker  */         
  16229.  /* of same, and not further distributed.  Such modifications should */         
  16230.  /* be mailed to the author for consideration for addition to the    */         
  16231.  /* software and incorporation in subsequent releases.               */         
  16232.  /*                                                                  */         
  16233.  /********************************************************************/         
  16234.                                                                                 
  16235. #pragma  csect(code,  "NN@IVGET")                                               
  16236. #pragma  csect(static,"NN$IVGET")                                               
  16237. #include "nn.h"                                                                 
  16238.                                                                                 
  16239. /****** Retrieve the value of an ISPF variable. **********************/         
  16240.                                                                                 
  16241. Bool                                                                            
  16242. NNMivget(np,varname,varbuf,varbuflen)                                           
  16243. Rstruc nncb *np;                                                                
  16244. char        *varname;                                                           
  16245. char        *varbuf;                                                            
  16246. int          varbuflen;                                                         
  16247. {                                                                               
  16248.  int         vcopy_length;                                                      
  16249.                                                                                 
  16250.  if (!strchr(varname,' ')) {                                                    
  16251.    fprintf(stderr,"NNMivget: no blank passed in var name\n");                   
  16252.    return FALSE;                                                                
  16253.  }                                                                              
  16254.                                                                                 
  16255.  /*                                                                             
  16256.   * If varbuflen is negative, that means that the value is not to be            
  16257.   * treated as a C string, and the null character is not to be                  
  16258.   * appended to the resulting value.  This is used for hex values               
  16259.   * (like addresses) that are stored in ISPF table row variables.               
  16260.   */                                                                            
  16261.                                                                                 
  16262.  if (varbuflen < 0)  vcopy_length = -varbuflen;                                 
  16263.  else vcopy_length = varbuflen;                                                 
  16264.                                                                                 
  16265.  /* Note that on entry, vcopy_length is an integer that contains                
  16266.     the length of the buffer.  On return it is updated to the length            
  16267.     of the value returned.  Since we have to stick a null character             
  16268.     on the end of it for C, the actual buffer passed must be at least           
  16269.     one character longer than the length as defined to ISPF.                    
  16270.  */                                                                             
  16271.                                                                                 
  16272.  np->ispfrc = ISPLINK("VCOPY",varname,&vcopy_length,varbuf,"MOVE");             
  16273.  switch (np->ispfrc) {                                                          
  16274.    case  0:                                                                     
  16275.            if (varbuflen >= 0)                                                  
  16276.               varbuf[vcopy_length] = '\0';                                      
  16277.            return TRUE;                                                         
  16278.    case  8:                                                                     
  16279.            strcpy(varbuf,"");                                                   
  16280.            return TRUE;                                                         
  16281.    case 16:                                                                     
  16282.            fprintf(stderr,                                                      
  16283.                    "Error: ISPF variable buffer too short to get %s\n",         
  16284.                    varname);                                                    
  16285.            return FALSE;                                                        
  16286.    default:                                                                     
  16287.            NNMierr(np);   /* handle ISPF error */                               
  16288.            return FALSE;                                                        
  16289.  }                                                                              
  16290. }                                                                               
  16291.                                                                                 
  16292. ./   ADD NAME=NNMIVPUT,SSI=01020029                                             
  16293.                                                                                 
  16294.  /********************************************************************/         
  16295.  /*                                                                  */         
  16296.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  16297.  /*                                                                  */         
  16298.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  16299.  /* including the implied warranties of merchantability and fitness, */         
  16300.  /* are expressly denied.                                            */         
  16301.  /*                                                                  */         
  16302.  /* Provided this copyright notice is included, this software may    */         
  16303.  /* be freely distributed and not offered for sale.                  */         
  16304.  /*                                                                  */         
  16305.  /* Changes or modifications may be made and used only by the maker  */         
  16306.  /* of same, and not further distributed.  Such modifications should */         
  16307.  /* be mailed to the author for consideration for addition to the    */         
  16308.  /* software and incorporation in subsequent releases.               */         
  16309.  /*                                                                  */         
  16310.  /********************************************************************/         
  16311.                                                                                 
  16312. #pragma  csect(code,  "NN@IVPUT")                                               
  16313. #pragma  csect(static,"NN$IVPUT")                                               
  16314. #include "nn.h"                                                                 
  16315.                                                                                 
  16316. /****** Set the value of an ISPF variable. ***************************/         
  16317.                                                                                 
  16318. Bool                                                                            
  16319. NNMivput(np,varname,varbuf,varlen)                                              
  16320. Rstruc nncb *np;                                                                
  16321. char        *varname;                                                           
  16322. char        *varbuf;                                                            
  16323. int         varlen;                                                             
  16324. {                                                                               
  16325.  int         vreplace_length;                                                   
  16326.                                                                                 
  16327.  vreplace_length = (varlen<0 ? strlen(varbuf) : varlen);                        
  16328.                                                                                 
  16329.  np->ispfrc = ISPLINK("VREPLACE",varname,&vreplace_length,varbuf);              
  16330.  switch (np->ispfrc) {                                                          
  16331.    case  0:                                                                     
  16332.            return TRUE;                                                         
  16333.    case 16:                                                                     
  16334.            fprintf(stderr,                                                      
  16335.                    "Error: ISPF variable buffer too short to put %s\n",         
  16336.                    varname);                                                    
  16337.            return FALSE;                                                        
  16338.    default:                                                                     
  16339.            NNMierr(np);   /* handle ISPF error */                               
  16340.            return FALSE;                                                        
  16341.  }                                                                              
  16342. }                                                                               
  16343.                                                                                 
  16344. ./   ADD NAME=NNMMAIN,SSI=01470001                                              
  16345.                                                                                 
  16346.  /********************************************************************/         
  16347.  /*                                                                  */         
  16348.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  16349.  /*                                                                  */         
  16350.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  16351.  /*                                                                  */         
  16352.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  16353.  /* including the implied warranties of merchantability and fitness, */         
  16354.  /* are expressly denied.                                            */         
  16355.  /*                                                                  */         
  16356.  /* Provided this copyright notice is included, this software may    */         
  16357.  /* be freely distributed and not offered for sale.                  */         
  16358.  /*                                                                  */         
  16359.  /* Changes or modifications may be made and used only by the maker  */         
  16360.  /* of same, and not further distributed.  Such modifications should */         
  16361.  /* be mailed to the author for consideration for addition to the    */         
  16362.  /* software and incorporation in subsequent releases.               */         
  16363.  /*                                                                  */         
  16364.  /********************************************************************/         
  16365.                                                                                 
  16366.  /********************************************************************/         
  16367.  /*                                                                  */         
  16368.  /*                             NNMVS                                */         
  16369.  /*                                                                  */         
  16370.  /*                   MVS news reader dialog driver                  */         
  16371.  /*                                                                  */         
  16372.  /*                            Author:                               */         
  16373.  /*                   Steve Bacher <seb@draper.com>                  */         
  16374.  /*                                                                  */         
  16375.  /*                    Enhancements contributed by:                  */         
  16376.  /*                  Dale Ingold <snoddi@mvs.sas.com>                */         
  16377.  /*                                                                  */         
  16378.  /*                      Version: 2  Release: 4                      */         
  16379.  /*                                                                  */         
  16380.  /********************************************************************/         
  16381.                                                                                 
  16382. #ifdef SASC                                                                     
  16383. #pragma  runopts(EXECOPS)                                                       
  16384. #else                                                                           
  16385. #pragma  runopts(heap(8k,8k,anywhere,))                                         
  16386. #pragma  runopts(nospie,nostae)                                                 
  16387. #endif                                                                          
  16388.                                                                                 
  16389. #pragma  csect(code,  "NN@MAIN ")                                               
  16390. #pragma  csect(static,"NN$MAIN ")                                               
  16391. #include "nn.h"                                                                 
  16392.                                                                                 
  16393. /*********************************************************************/         
  16394.                                                                                 
  16395. static char copyright_notice[] =                                                
  16396.    "Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992   \n\         
  16397.                                                                     \n\         
  16398.     SAS enhancements copyright (c) 1992 SAS Institute, Inc.         \n\         
  16399.                                                                     \n\         
  16400.     This software is provided on an 'AS IS' basis.  All warranties, \n\         
  16401.     including the implied warranties of merchantability and fitness,\n\         
  16402.     are expressly denied.                                           \n\         
  16403.                                                                     \n\         
  16404.     Provided this copyright notice is included, this software may   \n\         
  16405.     be freely distributed and not offered for sale.                 \n\         
  16406.                                                                     \n\         
  16407.     Changes or modifications may be made and used only by the maker \n\         
  16408.     of same, and not further distributed.  Such modifications should\n\         
  16409.     be mailed to the author for consideration for addition to the   \n\         
  16410.     software and incorporation in subsequent releases.";                        
  16411.                                                                                 
  16412. /*********************************************************************/         
  16413.                                                                                 
  16414. #ifdef I370                                                                     
  16415. char * _style = "tso:";                                                         
  16416. #endif                                                                          
  16417.                                                                                 
  16418. static Bool                                                                     
  16419. alloc_newsrc(newsrc_dsname,newsrc_ddname)                                       
  16420. char           *newsrc_dsname;                                                  
  16421. char           *newsrc_ddname;                                                  
  16422. {                                                                               
  16423.  int            space;                                                          
  16424.  char          *lparp;                                                          
  16425.  char          *rparp;                                                          
  16426.  FILE          *mfile;                                                          
  16427.  char           dsnseq [81];                                                    
  16428.  char           member [81];                                                    
  16429.  char           what_to_open [81];                                              
  16430.                                                                                 
  16431.  space = 2;                                                                     
  16432.  strcpy(member,"");                                                             
  16433.  strcpy(dsnseq,newsrc_dsname);                                                  
  16434.  lparp = strchr(dsnseq,'(');                                                    
  16435.  rparp = strchr(dsnseq,')');                                                    
  16436.  if (lparp && rparp && (lparp < rparp) && (*(rparp+1) == '\0')) {               
  16437.    *lparp = '\0';            /* makes dsnseq the seq part only */               
  16438.    *rparp = '\0';            /* turns member into a string     */               
  16439.    strcpy(member, lparp+1);                                                     
  16440.    space = 10;                                                                  
  16441.  }                                                                              
  16442.                                                                                 
  16443.  if (!NNMalloc(newsrc_dsname,newsrc_ddname,SEQ,space)) return FALSE;            
  16444.                                                                                 
  16445.  /* If the data set had a member specified, it may have been                    
  16446.   * allocated as NEW, or the member may not exist.  Therefore,                  
  16447.   * force the member to exist by opening it for output and closing              
  16448.   * it if it doesn't exist.  Then reallocate it as an existing                  
  16449.   * data set to prevent a B14 abend when we try to write a new                  
  16450.   * PDS + member for output and close it.                                       
  16451.   *                                                                             
  16452.   * Otherwise, make sure the data set is not empty by opening it                
  16453.   * in append mode - this also insures that it is writable.                     
  16454.   */                                                                            
  16455.                                                                                 
  16456.  if (*member) {                                                                 
  16457.    sprintf(what_to_open, "'%s(%s)'", dsnseq, member);                           
  16458.    mfile = fopen(what_to_open,"r");                                             
  16459.    if (!mfile && errno == 104) {        /* Member not found */                  
  16460.      mfile = fopen(what_to_open,"w");   /* create new member */                 
  16461.    }                                                                            
  16462.    if (!mfile) {                                                                
  16463.      perror(what_to_open);                                                      
  16464.      return FALSE;                                                              
  16465.    }                                                                            
  16466.    else if (fclose(mfile) < 0) {                                                
  16467.      fprintf(stderr, "Error closing %s\n", what_to_open);                       
  16468.      return FALSE;                                                              
  16469.    }                                                                            
  16470.    (void)NNMunalc(newsrc_ddname);                                               
  16471.    if (!NNMalloc(newsrc_dsname,newsrc_ddname,SEQ,0)) return FALSE;              
  16472.  }                                                                              
  16473.  else {                                                                         
  16474.    sprintf(what_to_open, "dd:%s", newsrc_ddname);                               
  16475.    mfile = fopen(what_to_open,"a");                                             
  16476.    if (!mfile) {                                                                
  16477.      perror(what_to_open);                                                      
  16478.      return FALSE;                                                              
  16479.    }                                                                            
  16480.    else if (fclose(mfile) < 0) {                                                
  16481.      fprintf(stderr, "Error closing %s\n", what_to_open);                       
  16482.      return FALSE;                                                              
  16483.    }                                                                            
  16484.  }                                                                              
  16485.                                                                                 
  16486.  return TRUE;                                                                   
  16487. }                                                                               
  16488.                                                                                 
  16489. /*********************************************************************/         
  16490.                                                                                 
  16491. int                                                                             
  16492. main(argc,argv)                                                                 
  16493. int      argc;                                                                  
  16494. char   **argv;                                                                  
  16495.                                                                                 
  16496. {                                                                               
  16497.  struct nncb            *np;                                                    
  16498.  char                   *p;                                                     
  16499.  Bool                  (*selection_processor)();                                
  16500.  struct hostent         *client_hp;                                             
  16501.  int                     gethostnamerc;                                         
  16502.  int                     exit_return_code;                                      
  16503.  Bool                    display_continue;                                      
  16504.  Bool                    ok_to_update_newsrc;                                   
  16505.  struct nncb             nn;                                                    
  16506.  char                    newsrc_dsname  [65];                                   
  16507.                                                                                 
  16508.  exit_return_code = 0;                                                          
  16509.                                                                                 
  16510.  memset(&nn,0,sizeof(struct nncb));                                             
  16511.                                                                                 
  16512.  np = &nn;                                                                      
  16513.                                                                                 
  16514.  np->test_mode  = FALSE;                                                        
  16515.  np->debug_mode = FALSE;                                                        
  16516.  np->batch_mode = FALSE;                                                        
  16517.  np->preselection = '\0';                                                       
  16518.  if (argc > 1) {                                                                
  16519.    p = argv[1];                                                                 
  16520.    if (*p == '-') {                                                             
  16521.      while (*++p) {                                                             
  16522.        switch (toupper(*p)) {                                                   
  16523.          case 'T':  np->test_mode  = TRUE;    break;                            
  16524.          case 'D':  np->debug_mode = TRUE;    break;                            
  16525.          case 'B':  np->batch_mode = TRUE;    break;                            
  16526.          case SELECTION_ALL:                                                    
  16527.          case SELECTION_REG:                                                    
  16528.          case SELECTION_NNTP:                                                   
  16529.          case SELECTION_GROUP:                                                  
  16530.          case SELECTION_LIST:                                                   
  16531.          case SELECTION_NEWG:                                                   
  16532.          case SELECTION_OPTS:                                                   
  16533.          case SELECTION_EXIT:                                                   
  16534.                     np->preselection = *p;    break;                            
  16535.          default: fprintf(stderr,"NNMVS: Bad parameter flag %c\n", *p);         
  16536.                   exit_return_code = 8;                                         
  16537.        }                                                                        
  16538.      }                                                                          
  16539.    }                                                                            
  16540.    else {                                                                       
  16541.      fprintf(stderr,"NNMVS: Bad parameter string %s\n",p);                      
  16542.      exit_return_code = 8;                                                      
  16543.    }                                                                            
  16544.  }                                                                              
  16545.                                                                                 
  16546.  if (np->test_mode) __ctest(NULL);                                              
  16547.                                                                                 
  16548.  if (np->debug_mode) {                                                          
  16549.    if (!(np->debug_file = fopen("dd:nndebug","w"))) {                           
  16550.      perror("debug file (DD NNDEBUG)");                                         
  16551.      exit_return_code = 4;                                                      
  16552.    }                                                                            
  16553.  }                                                                              
  16554.  else np->debug_file = NULL;                                                    
  16555.                                                                                 
  16556.  if (np->batch_mode) {                                                          
  16557.    if (!(np->batch_infile = fopen("dd:NNBATIN","r"))) {                         
  16558.      perror("batch input file (dd:NNBATIN)");                                   
  16559.    }                                                                            
  16560.    if (!(np->batch_outfile = fopen("dd:NNBATOUT","w"))) {                       
  16561.      perror("batch output file (dd:NNBATOUT)");                                 
  16562.    }                                                                            
  16563.  }                                                                              
  16564.  else {                                                                         
  16565.    np->batch_infile  = NULL;                                                    
  16566.    np->batch_outfile = NULL;                                                    
  16567.  }                                                                              
  16568.                                                                                 
  16569.  np->newsrc_file = NULL;                                                        
  16570.                                                                                 
  16571.  /* This doesn't work, and may even make things worse.                          
  16572.   * if (signal(SIGINT,attention_handler) == SIG_ERR) {                          
  16573.   *   fprintf(stderr,"Error: unable to establish attention handler.\n");        
  16574.   *   exit(27);                                                                 
  16575.   * }                                                                           
  16576.   */                                                                            
  16577.                                                                                 
  16578.  np->first_newsgroup      = NULL;                                               
  16579.  np->thdr.first_text_line = NULL;                                               
  16580.  NNMclrng(np);                    /* Clear newsgroups */                        
  16581.  NNMclrtx(np,NULL);               /* Clear text       */                        
  16582.                                                                                 
  16583.  np->g_bytes_returned = 0;                                                      
  16584.  np->g_buf_index      = -1;                                                     
  16585.                                                                                 
  16586.  /* Determine the local path name. */                                           
  16587.                                                                                 
  16588.  gethostnamerc = gethostname(np->client_hostname,MAXHOSTNAMELEN);               
  16589.  if (gethostnamerc < 0) {                                                       
  16590.    fprintf(stderr,"NNMVS: gethostname() failed, don't know my name\n");         
  16591.    exit_return_code = 8;                                                        
  16592.  }                                                                              
  16593.  else {                                                                         
  16594.    client_hp = gethostbyname(np->client_hostname);                              
  16595.    if (!client_hp) {                                                            
  16596.      fprintf(stderr,                                                            
  16597.              "NNMVS: gethostbyname() failed, can't get my name\n");             
  16598.      exit_return_code = 8;                                                      
  16599.    }                                                                            
  16600.    else {                                                                       
  16601.      strcpy(np->nnclient,np->client_hostname);                                  
  16602.      strcpy(np->client_hostname, client_hp->h_name);                            
  16603.      np->client_ip_address = *(IPADDRESS *)client_hp->h_addr;                   
  16604.    }                                                                            
  16605.  }                                                                              
  16606.                                                                                 
  16607.  strcpy(np->nnserver,"");                                                       
  16608.  np->connected_to_server   = FALSE;                                             
  16609.  np->closing_connection    = FALSE;                                             
  16610.  np->reconnect_in_progress = FALSE;                                             
  16611.  np->receiving_text        = FALSE;                                             
  16612.  np->newsgroup_selected    = FALSE;                                             
  16613.                                                                                 
  16614.  GETMAIN(np->server_buf,   char, SERVER_BUF_MSGSIZE+4,"server buffer");         
  16615.  GETMAIN(np->client_buf,   char, CLIENT_BUF_MSGSIZE+4,"client buffer");         
  16616.  GETMAIN(np->nntp_command, char, CLIENT_BUF_MSGSIZE+4,"NNTP command");          
  16617.                                                                                 
  16618.  if (exit_return_code > 4) /* nothing */;                                       
  16619.  else if (np->batch_mode) {                                                     
  16620.    exit_return_code = NNMbatch(np);                                             
  16621.  }                                                                              
  16622.  else {                                                                         
  16623.                                                                                 
  16624. #ifdef FETCH                                                                    
  16625.                                                                                 
  16626.    np->isplink_pointer = (int (*) ())fetch("ISPLINK");                          
  16627.    np->ispexec_pointer = (int (*) ())fetch("ISPEXEC");                          
  16628.                                                                                 
  16629. #endif                                                                          
  16630.                                                                                 
  16631.    if (!NNMispf(np,"CONTROL ERRORS RETURN")) exit_return_code = 20;             
  16632.                                                                                 
  16633.    else {                                                                       
  16634.                                                                                 
  16635.      NNMinit(np);  /* Set up command and selection code tables */               
  16636.                                                                                 
  16637.      (void)NNMivput(np,"ZCMD "    ,"",-1);                                      
  16638.      (void)NNMivput(np,"NNCURSOR ","",-1);                                      
  16639.                                                                                 
  16640.      NNMsopt(np,OPTION_ALL); /* Set options */                                  
  16641.                                                                                 
  16642.      strcpy(np->newsrc_to_open,"dd:");                                          
  16643.                                                                                 
  16644.      do {                                                                       
  16645.        NNMunalc(np->newsrc_to_open+3);                                          
  16646.        switch (NNMdmenu(np,&selection_processor)) {  /* Display menu */         
  16647.          case DISPLAY_REPEAT:                                                   
  16648.          case DISPLAY_ERROR:   display_continue = TRUE;  break;                 
  16649.          case DISPLAY_EXIT:                                                     
  16650.          case DISPLAY_FAILURE: display_continue = FALSE; break;                 
  16651.        }                                                                        
  16652.        if (display_continue                                                     
  16653.         && selection_processor                                                  
  16654.         && NNMivget(np,"NNNEWSRC ",newsrc_dsname,sizeof(newsrc_dsname))         
  16655.         && alloc_newsrc(newsrc_dsname,np->newsrc_to_open+3)) {                  
  16656.          NNMclrng(np);                          /* Clear newsgroups */          
  16657.          NNMclrtx(np,NULL);                     /* Clear text       */          
  16658.          NNMonrf(np,NULL);                      /* Open NEWSRC file */          
  16659.          (void)NNMivput(np,"ZCMD ","",-1);      /* Clear ZCMD field */          
  16660.                                                                                 
  16661.          /* Call selected function. If returns TRUE, rewrite NEWSRC */          
  16662.                                                                                 
  16663.          ok_to_update_newsrc = (*selection_processor)(np);                      
  16664.          NNMcnrf(np,NULL,                                                       
  16665.                  ok_to_update_newsrc); /* Close/rewrite NEWSRC file */          
  16666.        }                                                                        
  16667.      } while (display_continue && !np->quit);                                   
  16668.                                                                                 
  16669.      exit_return_code = 0;                                                      
  16670.                                                                                 
  16671.    }                                                                            
  16672.                                                                                 
  16673.  }                                                                              
  16674.                                                                                 
  16675.  if (*np->maildsn) {                                                            
  16676.    if (remove(np->maildsn) < 0) {                                               
  16677.      fprintf(stderr,"NNMVS: Error removing mail dataset %s\n");                 
  16678.    }                                                                            
  16679.  }                                                                              
  16680.                                                                                 
  16681.  if (np->connected_to_server) {                                                 
  16682.    NNMdisc(np);                 /* disconnect from news server */               
  16683.  }                                                                              
  16684.                                                                                 
  16685.  NNMclrng(np);                  /* Clear newsgroups */                          
  16686.                                                                                 
  16687.  FREEMAIN(np->nntp_command,"nntp command");                                     
  16688.  FREEMAIN(np->server_buf,  "server buffer");                                    
  16689.  FREEMAIN(np->client_buf,  "client buffer");                                    
  16690.                                                                                 
  16691.  #define FINAL_CLOSE(A,B) \                                                     
  16692.    if (A) { \                                                                   
  16693.             if (fclose(A) < 0) fprintf(stderr,B); \                             
  16694.           }                                                                     
  16695.                                                                                 
  16696.  FINAL_CLOSE(np->newsrc_file   , "Error closing newsrc file\n");                
  16697.  FINAL_CLOSE(np->debug_file    , "Error closing debug file\n");                 
  16698.  FINAL_CLOSE(np->batch_infile  , "Error closing batch input file\n");           
  16699.  FINAL_CLOSE(np->batch_outfile , "Error closing batch output file\n");          
  16700.                                                                                 
  16701.  exit(exit_return_code);                                                        
  16702. }                                                                               
  16703.                                                                                 
  16704. ./   ADD NAME=NNMMARR,SSI=01060023                                              
  16705.                                                                                 
  16706.  /********************************************************************/         
  16707.  /*                                                                  */         
  16708.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  16709.  /*                                                                  */         
  16710.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  16711.  /* including the implied warranties of merchantability and fitness, */         
  16712.  /* are expressly denied.                                            */         
  16713.  /*                                                                  */         
  16714.  /* Provided this copyright notice is included, this software may    */         
  16715.  /* be freely distributed and not offered for sale.                  */         
  16716.  /*                                                                  */         
  16717.  /* Changes or modifications may be made and used only by the maker  */         
  16718.  /* of same, and not further distributed.  Such modifications should */         
  16719.  /* be mailed to the author for consideration for addition to the    */         
  16720.  /* software and incorporation in subsequent releases.               */         
  16721.  /*                                                                  */         
  16722.  /********************************************************************/         
  16723.                                                                                 
  16724. #pragma  csect(code,  "NN@MARR ")                                               
  16725. #pragma  csect(static,"NN$MARR ")                                               
  16726. #include "nn.h"                                                                 
  16727.                                                                                 
  16728. /****** Make article read. *******************************************/         
  16729.                                                                                 
  16730. void                                                                            
  16731. NNMmarr(np,gp,ap)                                                               
  16732. Rstruc nncb         *np;                                                        
  16733. Rstruc newsgroup    *gp;                                                        
  16734. Rstruc newsarticle  *ap;                                                        
  16735. {                                                                               
  16736.  register VARK      *vp = &V_STATUS(gp,ap->number);                             
  16737.                                                                                 
  16738.  if (*vp == V_UNREAD) {                                                         
  16739.    *vp = V_READ;                                                                
  16740.    gp->real_unread_count--;                                                     
  16741.  }                                                                              
  16742.  ap->action = READ;                                                             
  16743.                                                                                 
  16744.  return;                                                                        
  16745. }                                                                               
  16746.                                                                                 
  16747. ./   ADD NAME=NNMMARU,SSI=01060051                                              
  16748.                                                                                 
  16749.  /********************************************************************/         
  16750.  /*                                                                  */         
  16751.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  16752.  /*                                                                  */         
  16753.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  16754.  /* including the implied warranties of merchantability and fitness, */         
  16755.  /* are expressly denied.                                            */         
  16756.  /*                                                                  */         
  16757.  /* Provided this copyright notice is included, this software may    */         
  16758.  /* be freely distributed and not offered for sale.                  */         
  16759.  /*                                                                  */         
  16760.  /* Changes or modifications may be made and used only by the maker  */         
  16761.  /* of same, and not further distributed.  Such modifications should */         
  16762.  /* be mailed to the author for consideration for addition to the    */         
  16763.  /* software and incorporation in subsequent releases.               */         
  16764.  /*                                                                  */         
  16765.  /********************************************************************/         
  16766.                                                                                 
  16767. #pragma  csect(code,  "NN@MARU ")                                               
  16768. #pragma  csect(static,"NN$MARU ")                                               
  16769. #include "nn.h"                                                                 
  16770.                                                                                 
  16771. /****** Make article unread. *****************************************/         
  16772.                                                                                 
  16773. void                                                                            
  16774. NNMmaru(np,gp,ap)                                                               
  16775. Rstruc nncb         *np;                                                        
  16776. Rstruc newsgroup    *gp;                                                        
  16777. Rstruc newsarticle  *ap;                                                        
  16778. {                                                                               
  16779.  register VARK      *vp = &V_STATUS(gp,ap->number);                             
  16780.                                                                                 
  16781.  if (*vp == V_READ) {                                                           
  16782.    *vp = V_UNREAD;                                                              
  16783.    gp->real_unread_count++;                                                     
  16784.  }                                                                              
  16785.  ap->action = UNREAD;                                                           
  16786.                                                                                 
  16787.  return;                                                                        
  16788. }                                                                               
  16789.                                                                                 
  16790. ./   ADD NAME=NNMNNTP,SSI=01070017                                              
  16791.                                                                                 
  16792.  /********************************************************************/         
  16793.  /*                                                                  */         
  16794.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  16795.  /*                                                                  */         
  16796.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  16797.  /* including the implied warranties of merchantability and fitness, */         
  16798.  /* are expressly denied.                                            */         
  16799.  /*                                                                  */         
  16800.  /* Provided this copyright notice is included, this software may    */         
  16801.  /* be freely distributed and not offered for sale.                  */         
  16802.  /*                                                                  */         
  16803.  /* Changes or modifications may be made and used only by the maker  */         
  16804.  /* of same, and not further distributed.  Such modifications should */         
  16805.  /* be mailed to the author for consideration for addition to the    */         
  16806.  /* software and incorporation in subsequent releases.               */         
  16807.  /*                                                                  */         
  16808.  /********************************************************************/         
  16809.                                                                                 
  16810. #pragma  csect(code,  "NN@NNTP ")                                               
  16811. #pragma  csect(static,"NN$NNTP ")                                               
  16812. #include "nn.h"                                                                 
  16813.                                                                                 
  16814. /****** Read server data. ********************************************/         
  16815.                                                                                 
  16816. static Bool                                                                     
  16817. read_server_data(np)                                                            
  16818. Rstruc nncb         *np;                                                        
  16819. {                                                                               
  16820.  char               *lp;                                                        
  16821.                                                                                 
  16822.  NNMclrtx(np,NULL);                   /* Clear text */                          
  16823.                                                                                 
  16824.  do {                                                                           
  16825.                                                                                 
  16826.    if (NNMgsrvl(np,&lp))              /* Get server line */                     
  16827.      if (lp)                                                                    
  16828.        (void)NNMouttx(np,lp,NULL);   /* Output text line */                     
  16829.                                                                                 
  16830.  } while (lp);                                                                  
  16831.                                                                                 
  16832.  if (np->time_to_go_home == TRUE) return FALSE;                                 
  16833.  else return TRUE;                                                              
  16834. }                                                                               
  16835.                                                                                 
  16836. /************ Execute native NNTP protocol commands. *****************/         
  16837.                                                                                 
  16838. void                                                                            
  16839. NNMnntp(np)                                                                     
  16840. Rstruc nncb *np;                                                                
  16841. {                                                                               
  16842.                                                                                 
  16843.  /* np->nntp_command must contain NNTP command */                               
  16844.                                                                                 
  16845.  if (!np->receiving_text && *np->nntp_command == '\0') return;                  
  16846.                                                                                 
  16847.  np->newsgroup_selected = FALSE;  /* in case we change server's state           
  16848.                                      with a command like "GROUP xxx" */         
  16849.                                                                                 
  16850.  if (!NNMsockt(np)) return;      /* Send socket command to server */            
  16851.  if (!read_server_data(np,NULL)) return;      /* Read server data */            
  16852.  NNMvtx(np,NULL,NULL);                        /* View text        */            
  16853.  return;                                                                        
  16854. }                                                                               
  16855.                                                                                 
  16856. ./   ADD NAME=NNMONRF,SSI=01150040                                              
  16857.                                                                                 
  16858.  /********************************************************************/         
  16859.  /*                                                                  */         
  16860.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  16861.  /*                                                                  */         
  16862.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  16863.  /*                                                                  */         
  16864.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  16865.  /* including the implied warranties of merchantability and fitness, */         
  16866.  /* are expressly denied.                                            */         
  16867.  /*                                                                  */         
  16868.  /* Provided this copyright notice is included, this software may    */         
  16869.  /* be freely distributed and not offered for sale.                  */         
  16870.  /*                                                                  */         
  16871.  /* Changes or modifications may be made and used only by the maker  */         
  16872.  /* of same, and not further distributed.  Such modifications should */         
  16873.  /* be mailed to the author for consideration for addition to the    */         
  16874.  /* software and incorporation in subsequent releases.               */         
  16875.  /*                                                                  */         
  16876.  /********************************************************************/         
  16877.                                                                                 
  16878. #pragma  csect(code,  "NN@ONRF ")                                               
  16879. #pragma  csect(static,"NN$ONRF ")                                               
  16880. #include "nn.h"                                                                 
  16881.                                                                                 
  16882. /****** Open NEWSRC file. ********************************************/         
  16883.                                                                                 
  16884. void                                                                            
  16885. NNMonrf(np,what_to_open)                                                        
  16886. Rstruc nncb         *np;                                                        
  16887. char                *what_to_open;                                              
  16888. {                                                                               
  16889.  char                newsrc_line[256];                                          
  16890.  char                newsrc_name[GROUP_NAME_SIZE];                              
  16891.  Rstruc newsgroup   *gp;                                                        
  16892.  register char      *nlp;                                                       
  16893.  char               *temp;                                                      
  16894.  int                 sscanf_rc;                                                 
  16895.  int                 newsrc_registered;                                         
  16896.  int                 newsrc_unread;                                             
  16897.  int                 newsrc_topnum;                                             
  16898.  int                 newsrc_scan_count;                                         
  16899.  int                 newsrc_save_length;                                        
  16900.                                                                                 
  16901.  if (!what_to_open) what_to_open = np->newsrc_to_open;                          
  16902.                                                                                 
  16903.  /* If the file does not exist, then create it. */                              
  16904.  /* Actually, we're not going to do that here.  In order to prevent             
  16905.   * starting up more than one news server in a single TSO session,              
  16906.   * we use the ddname allocation as a cheap serialization hack.                 
  16907.   * In other words, we assume that the exec that starts up this                 
  16908.   * program (in addition to making sure that the ISPF environment               
  16909.   * is all set up) allocates ddname NNNEWSRC as OLD.  In that way,              
  16910.   * only one news server can start up at a time.  And if this file              
  16911.   * is not present, the news server will refuse to start.                       
  16912.   *                                                                             
  16913.   * The same startup exec will also insure that a file allocated to             
  16914.   * ddname NNNEWSRC exists.  If it had to be created anew, it will              
  16915.   * be empty.  Which is OK, because that means that the user has                
  16916.   * saved no news state up until this point.                                    
  16917.   *                                                                             
  16918.   * Flash - the above is no longer true.  We permit multiple news               
  16919.   * readers, as long as they are talking to different news servers              
  16920.   * and using different NEWSRC files.                                           
  16921.   */                                                                            
  16922.                                                                                 
  16923.  newsrc_scan_count = 0;                                                         
  16924.  np->brand_new_newsrc = TRUE;                                                   
  16925.                                                                                 
  16926.  errno = 0;                                                                     
  16927.                                                                                 
  16928.  if (!(np->newsrc_file = fopen(what_to_open,"r"))) {                            
  16929.    if (errno == 104) {  /* Member not found */                                  
  16930.      if (!(np->newsrc_file = fopen(what_to_open,"w"))) {                        
  16931.        perror("Cannot create NEWSRC PDS member");                               
  16932.      }                                                                          
  16933.      else if (fclose(np->newsrc_file) < 0) {                                    
  16934.        fprintf(stderr, "Error closing %s\n", what_to_open);                     
  16935.        np->newsrc_file = NULL;                                                  
  16936.      }                                                                          
  16937.      else np->newsrc_file = fopen(what_to_open,"r");                            
  16938.    }                                                                            
  16939.    else perror("Cannot open NEWSRC file");                                      
  16940.  }                                                                              
  16941.  if (!np->newsrc_file) {                                                        
  16942.    fprintf(stderr,"Severe error, NEWSRC file cannot be opened.\n");             
  16943.    if (!np->batch_mode) {                                                       
  16944.      (void)NNMdispl(np,"NNMRCERR");                                             
  16945.    }                                                                            
  16946.    exit(12);                                                                    
  16947.  }                                                                              
  16948.                                                                                 
  16949.  np->new_newsgroup_count = 0;                                                   
  16950.                                                                                 
  16951.  /* Read from the file, saving the state information. */                        
  16952.                                                                                 
  16953.  /********************************************************************/         
  16954.  /*                                                                  */         
  16955.  /* Note:  The format used here is designed to be compatible with    */         
  16956.  /*        the format used by ANU-NEWS.  This is not an attempt to   */         
  16957.  /*        duplicate the "look and feel" of ANU-NEWS - it is just    */         
  16958.  /*        to be compatible with the saved state of VAX NEWS users.  */         
  16959.  /*                                                                  */         
  16960.  /********************************************************************/         
  16961.                                                                                 
  16962.  if (feof(np->newsrc_file)) return;                                             
  16963.                                                                                 
  16964.  /* First line: time in hex digits of last "registration", and some             
  16965.   * other junk.  We now interpret this as the last time the status              
  16966.   * of the server's newsgroups was interrogated (LIST or NEWGROUPS)             
  16967.   * and save it.                                                                
  16968.   */                                                                            
  16969.                                                                                 
  16970.  fgets(newsrc_line,sizeof(newsrc_line),np->newsrc_file);                        
  16971.  if (strlen(newsrc_line) >= 13)      /* if new format .newsrc file  */          
  16972.     sscanf(newsrc_line, "%6c %6c", &np->lastNGdate, &np->lastNGtime);           
  16973.                                                                                 
  16974.  if (feof(np->newsrc_file)) return;                                             
  16975.                                                                                 
  16976.  /* The rest of the file consists of information about newsgroups.              
  16977.     Read until end of file or one of the special markers is found. */           
  16978.                                                                                 
  16979.  fgets(newsrc_line,sizeof(newsrc_line),np->newsrc_file);                        
  16980.  for (;;) {                                                                     
  16981.    if (feof(np->newsrc_file))            break;                                 
  16982.    if (EQUAL(newsrc_line,"MARKLIST\n"))  break;                                 
  16983.    if (EQUAL(newsrc_line,"KILLLIST\n"))  break;                                 
  16984.    if (EQUAL(newsrc_line,"PROFILE\n"))   break;                                 
  16985.                                                                                 
  16986.  /* For each line, build a newsgroup entry and fill it in with                  
  16987.     the values taken from the input line. */                                    
  16988.                                                                                 
  16989.  /* Right now we are not checking for {classname,classname} as we               
  16990.     don't know how, and it would complicate things. */                          
  16991.                                                                                 
  16992.    nlp = strchr(newsrc_line,':');                                               
  16993.    if (nlp == NULL) nlp = strchr(newsrc_line,'\n');                             
  16994.    if (nlp == NULL) {                                                           
  16995.      fprintf(stderr,"Bad name in newsrc file, ignored:\n%s\n\n",                
  16996.                     newsrc_line);                                               
  16997.      fgets(newsrc_line,sizeof(newsrc_line),np->newsrc_file);                    
  16998.      continue;                                                                  
  16999.    }                                                                            
  17000.    memcpy(newsrc_name,newsrc_line,nlp-newsrc_line);                             
  17001.    newsrc_name[nlp-newsrc_line] = '\0';                                         
  17002.    if (*nlp == '\n' || *(nlp+1) == '\n') sscanf_rc = 0;                         
  17003.    else                                                                         
  17004.     sscanf_rc = sscanf(nlp,": (%d) [%d,%d] %n",                                 
  17005.                              &newsrc_registered,                                
  17006.                              &newsrc_unread,                                    
  17007.                              &newsrc_topnum,                                    
  17008.                              &newsrc_scan_count);                               
  17009.                                                                                 
  17010.    switch (sscanf_rc) {    /* Note use of switch WITHOUT break here. */         
  17011.       case EOF: newsrc_registered = 1;                                          
  17012.       case 0:   newsrc_registered = 1;                                          
  17013.       case 1:   newsrc_unread     = 0;                                          
  17014.       case 2:   newsrc_topnum     = 0;                                          
  17015.                 nlp = NULL;                                                     
  17016.       case 3:   break;                                                          
  17017.       default:  break;                                                          
  17018.    }                                                                            
  17019.                                                                                 
  17020.    np->brand_new_newsrc = FALSE;                                                
  17021.                                                                                 
  17022.    /* Allocate a newsgroup for this record. */                                  
  17023.                                                                                 
  17024.    gp = NNMaddng(np,newsrc_name);     /* Add newsgroup */                       
  17025.    if (!gp) {                                                                   
  17026.       fprintf(stderr,"Cannot initialize newsgroup: %s\n",newsrc_name);          
  17027.       fgets(newsrc_line,sizeof(newsrc_line),np->newsrc_file);                   
  17028.       continue;                                                                 
  17029.    }                                                                            
  17030.                                                                                 
  17031.    /* Now, collect the information on what articles were read. */               
  17032.                                                                                 
  17033.    SetGroupFromNewsrc(gp);                                                      
  17034.    gp->fake_first_article_number  = 1;                                          
  17035.    gp->fake_last_article_number   = newsrc_topnum;                              
  17036.    gp->fake_article_count         = newsrc_topnum;                              
  17037.    gp->fake_unread_count          = newsrc_unread;                              
  17038.    gp->registered                 = newsrc_registered;                          
  17039.                                                                                 
  17040.    if (gp->registered == -1) {                                                  
  17041.      SetNewGroup(gp);                                                           
  17042.      gp->registered = 0;                                                        
  17043.      np->new_newsgroup_count++;                                                 
  17044.    }                                                                            
  17045.                                                                                 
  17046.    /* Using the "topnum" field, allocate storage for those articles */          
  17047.    /*                                                                           
  17048.     * We won't do this yet - now we just save the NEWSRC line and               
  17049.     * create the article vector later, when we really need it.                  
  17050.     *                                                                           
  17051.     * if (!NNMallav(np,gp)) {   -- Allocate article vector --                   
  17052.     *   fprintf(stderr,"Error building newsgroups, terminating.\n");            
  17053.     *   return;                                                                 
  17054.     * }                                                                         
  17055.     */                                                                          
  17056.                                                                                 
  17057.    if (nlp == NULL) {                                                           
  17058.      fgets(newsrc_line,sizeof(newsrc_line),np->newsrc_file);                    
  17059.      continue;                                                                  
  17060.    }                                                                            
  17061.                                                                                 
  17062.    nlp += newsrc_scan_count;                                                    
  17063.                                                                                 
  17064.    /* Save the newsrc data (following the [unread,topnum] spec) */              
  17065.                                                                                 
  17066.    if (gp->saved_newsrc_line != gp->saved_newsrc_data) {                        
  17067.      FREEMAIN(gp->saved_newsrc_line,"stale saved newsrc line");                 
  17068.    }                                                                            
  17069.    if (*nlp == '\0') nlp = "\n";                                                
  17070.    newsrc_save_length = strlen(nlp) + 1;                                        
  17071.    if (newsrc_save_length <= sizeof(gp->saved_newsrc_data)) {                   
  17072.      gp->saved_newsrc_line = gp->saved_newsrc_data;                             
  17073.    }                                                                            
  17074.    else {                                                                       
  17075.      GETMAIN(gp->saved_newsrc_line,char,newsrc_save_length,                     
  17076.              "saved newsrc line");                                              
  17077.      if (!gp->saved_newsrc_line) {                                              
  17078.        fprintf(stderr,"Cannot save newsrc line for %s, terminating.\n",         
  17079.                       newsrc_name);                                             
  17080.        return;                                                                  
  17081.      }                                                                          
  17082.    }                                                                            
  17083.    strcpy(gp->saved_newsrc_line,nlp);                                           
  17084.                                                                                 
  17085.    for (;;) {                                                                   
  17086.                                                                                 
  17087.      fgets(newsrc_line,sizeof(newsrc_line),np->newsrc_file);                    
  17088.      if (feof(np->newsrc_file)) break;                                          
  17089.      if (newsrc_line[0] != ' ') break;                                          
  17090.      nlp = newsrc_line;                                                         
  17091.      GETMAIN(temp,char,strlen(gp->saved_newsrc_line)+strlen(nlp)+1,             
  17092.                        "saved newsrc line continuation");                       
  17093.      if (!temp) {                                                               
  17094.        fprintf(stderr,"Cannot save newsrc line for %s, terminating.\n",         
  17095.                       newsrc_name);                                             
  17096.        return;                                                                  
  17097.      }                                                                          
  17098.      strcpy(temp,gp->saved_newsrc_line);  /* should include newline */          
  17099.      strcat(temp,nlp);                                                          
  17100.      if (gp->saved_newsrc_line != gp->saved_newsrc_data) {                      
  17101.        FREEMAIN(gp->saved_newsrc_line,"old saved newsrc line");                 
  17102.      }                                                                          
  17103.      gp->saved_newsrc_line = temp;                                              
  17104.                                                                                 
  17105.    } /* end for - at this point we have no more newsrc continuations */         
  17106.                                                                                 
  17107.    /*** NNMpnrl(np,gp); -- Parse NEWSRC line -- ***/                            
  17108.                                                                                 
  17109.  } /* end for - at this point we have finished reading newsrc */                
  17110.                                                                                 
  17111.  /* Ignore everything once MARKLIST, KILLLIST, or PROFILE is seen.              
  17112.     We don't handle any of that stuff. */                                       
  17113.                                                                                 
  17114.  return;                                                                        
  17115. }                                                                               
  17116.                                                                                 
  17117. ./   ADD NAME=NNMOUTTX,SSI=01080042                                             
  17118.                                                                                 
  17119.  /********************************************************************/         
  17120.  /*                                                                  */         
  17121.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  17122.  /*                                                                  */         
  17123.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  17124.  /* including the implied warranties of merchantability and fitness, */         
  17125.  /* are expressly denied.                                            */         
  17126.  /*                                                                  */         
  17127.  /* Provided this copyright notice is included, this software may    */         
  17128.  /* be freely distributed and not offered for sale.                  */         
  17129.  /*                                                                  */         
  17130.  /* Changes or modifications may be made and used only by the maker  */         
  17131.  /* of same, and not further distributed.  Such modifications should */         
  17132.  /* be mailed to the author for consideration for addition to the    */         
  17133.  /* software and incorporation in subsequent releases.               */         
  17134.  /*                                                                  */         
  17135.  /********************************************************************/         
  17136.                                                                                 
  17137. #pragma  csect(code,  "NN@OUTTX")                                               
  17138. #pragma  csect(static,"NN$OUTTX")                                               
  17139. #include "nn.h"                                                                 
  17140.                                                                                 
  17141. /****** Output a line of text retrieved from the server. *************/         
  17142.                                                                                 
  17143. struct textline *                                                               
  17144. NNMouttx(np,line,ap)                                                            
  17145. Rstruc nncb         *np;                                                        
  17146. char                *line;                                                      
  17147. Rstruc newsarticle  *ap;                                                        
  17148.                                                                                 
  17149. {                                                                               
  17150.  struct texthdr     *thp;                                                       
  17151.  struct textline    *tp;                                                        
  17152.  short              line_length;                                                
  17153.  short              total_text_length;                                          
  17154.  short              tab_expansion_length;                                       
  17155.  Bool               tabs_present;                                               
  17156.  char              *p;                                                          
  17157.  char              *q;                                                          
  17158.  char              *t;                                                          
  17159.  int                e;                                                          
  17160.  int                u;                                                          
  17161.                                                                                 
  17162.  static char        tab_expansion_buffer[8*TEXT_BYTES];                         
  17163.                                                                                 
  17164.  /* If article is not specified, use main nncb, else article's text */          
  17165.                                                                                 
  17166.  thp = (ap ? &ap->thdr : &np->thdr);                                            
  17167.                                                                                 
  17168.  /* If line starts with double period, make it a single period. */              
  17169.                                                                                 
  17170.  if (ap && memcmp(line,"..",2) == 0) line++;                                    
  17171.                                                                                 
  17172.  /* Add this line to the current queue of server text lines. */                 
  17173.                                                                                 
  17174.  /* First, expand tabs in the line. */                                          
  17175.                                                                                 
  17176.  line_length = strlen(line);                                                    
  17177.  t = strchr(line,'\t');                                                         
  17178.  if (t == NULL) {                                                               
  17179.    tabs_present = FALSE;                                                        
  17180.    total_text_length = line_length + 1;                                         
  17181.  }                                                                              
  17182.  else {                                   /* expand tabs */                     
  17183.    tabs_present = TRUE;                                                         
  17184.    p = line;                                                                    
  17185.    q = line + line_length;                                                      
  17186.    e = 0;                                                                       
  17187.    memset(tab_expansion_buffer,' ',sizeof(tab_expansion_buffer));               
  17188.    while (TRUE) {                                                               
  17189.      u = t-p;                                                                   
  17190.      if (u > 0) {                                                               
  17191.        memcpy(tab_expansion_buffer+e,p,u);                                      
  17192.        e += u;                                                                  
  17193.      }                                                                          
  17194.      if (t == q) break;                                                         
  17195.      e = e / 8 * 8 + 8;                                                         
  17196.      p = t+1;                                                                   
  17197.      t = strchr(p,'\t');                                                        
  17198.      if (t == NULL) t = q;                                                      
  17199.    }                                                                            
  17200.    tab_expansion_length = e;                                                    
  17201.    tab_expansion_buffer[tab_expansion_length] = '\0';                           
  17202.    total_text_length = line_length + tab_expansion_length + 1;                  
  17203.  }                                                                              
  17204.                                                                                 
  17205.  GETMAIN(tp, char, offsetof(struct textline, text) + total_text_length,         
  17206.                    "text line");                                                
  17207.                                                                                 
  17208.  if (tp == NULL) {                                                              
  17209.    ERR1("There is not enough virtual storage to process server text.");         
  17210.    return NULL;                                                                 
  17211.  }                                                                              
  17212.                                                                                 
  17213.  tp->next = NULL;                                                               
  17214.  tp->text_length = line_length;                                                 
  17215.  strcpy(tp->text,line);                                                         
  17216.  if (tabs_present) {                                                            
  17217.    tp->tab_expanded_text_length = tab_expansion_length;                         
  17218.    tp->tab_expanded_text = tp->text + line_length;                              
  17219.    strcpy(tp->tab_expanded_text,tab_expansion_buffer);                          
  17220.  }                                                                              
  17221.  else {                                                                         
  17222.    tp->tab_expanded_text_length = line_length;                                  
  17223.    tp->tab_expanded_text = tp->text;                                            
  17224.  }                                                                              
  17225.                                                                                 
  17226.  if (thp->last_text_line == NULL) {                                             
  17227.    thp->first_text_line   = tp;                                                 
  17228.    thp->text_body_line    = tp;                                                 
  17229.    thp->current_text_line = tp;                                                 
  17230.  }                                                                              
  17231.  else thp->last_text_line->next = tp;                                           
  17232.                                                                                 
  17233.  thp->last_text_line = tp;                                                      
  17234.  thp->text_line_count++;                                                        
  17235.                                                                                 
  17236.  if (thp->text_max_length < tp->text_length)                                    
  17237.      thp->text_max_length = tp->text_length;                                    
  17238.  if (thp->text_max_tab_expanded_length < tp->tab_expanded_text_length)          
  17239.      thp->text_max_tab_expanded_length = tp->tab_expanded_text_length;          
  17240.                                                                                 
  17241.  return tp;                                                                     
  17242.                                                                                 
  17243. }                                                                               
  17244.                                                                                 
  17245. ./   ADD NAME=NNMPICK,SSI=01190028                                              
  17246.                                                                                 
  17247.  /********************************************************************/         
  17248.  /*                                                                  */         
  17249.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  17250.  /*                                                                  */         
  17251.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  17252.  /*                                                                  */         
  17253.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  17254.  /* including the implied warranties of merchantability and fitness, */         
  17255.  /* are expressly denied.                                            */         
  17256.  /*                                                                  */         
  17257.  /* Provided this copyright notice is included, this software may    */         
  17258.  /* be freely distributed and not offered for sale.                  */         
  17259.  /*                                                                  */         
  17260.  /* Changes or modifications may be made and used only by the maker  */         
  17261.  /* of same, and not further distributed.  Such modifications should */         
  17262.  /* be mailed to the author for consideration for addition to the    */         
  17263.  /* software and incorporation in subsequent releases.               */         
  17264.  /*                                                                  */         
  17265.  /********************************************************************/         
  17266.                                                                                 
  17267. #pragma  csect(code,  "NN@PICK ")                                               
  17268. #pragma  csect(static,"NN$PICK ")                                               
  17269. #include "nn.h"                                                                 
  17270.                                                                                 
  17271. /****** Collect text. ************************************************/         
  17272.                                                                                 
  17273. static void                                                                     
  17274. collect_text(np,ap)                                                             
  17275. Rstruc nncb         *np;                                                        
  17276. Rstruc newsarticle  *ap;                                                        
  17277. {                                                                               
  17278.  char               *lp;                                                        
  17279.                                                                                 
  17280.  np->sending_text = TRUE;                                                       
  17281.                                                                                 
  17282.  for (;;) {                                                                     
  17283.                                                                                 
  17284.    if (!NNMgsrvl(np,&lp))         break; /* Get server line */                  
  17285.    if (lp == NULL)                break;                                        
  17286.    if (strcmp(lp,".") == 0)       break;                                        
  17287.    if (!NNMouttx(np,lp,ap))       break; /* Output text line */                 
  17288.                                                                                 
  17289.  }                                                                              
  17290.                                                                                 
  17291.  return;                                                                        
  17292.                                                                                 
  17293. }                                                                               
  17294.                                                                                 
  17295. /****** Maybe suppress header line. **********************************/         
  17296.                                                                                 
  17297. static void                                                                     
  17298. maybe_suppress_header_line(np,ap,tp,header_name)                                
  17299. Rstruc nncb         *np;                                                        
  17300. Rstruc newsarticle  *ap;                                                        
  17301. Rstruc textline     *tp;                                                        
  17302. char                *header_name;                                               
  17303. {                                                                               
  17304.  char                temphdr[INTERNET_SIZE+2];                                  
  17305.  Bool                suppress;                                                  
  17306.                                                                                 
  17307. #define  SET_SUPPRESS(A)      A |= 0x8000                                       
  17308. #define  UNSET_SUPPRESS(A)    A &= 0x7fff                                       
  17309.                                                                                 
  17310.  switch (np->nnrfcopt[0]) {                                                     
  17311.    case '\0':                                                                   
  17312.    case 'A':                /* show all RFC822 headers */                       
  17313.               suppress = FALSE;                                                 
  17314.               break;                                                            
  17315.    case 'B':                /* show all except those in exclude list */         
  17316.               sprintf(temphdr," %s ",header_name);                              
  17317.               if (strstr(np->nnrfcexc,temphdr)) suppress = TRUE;                
  17318.               else                              suppress = FALSE;               
  17319.               break;                                                            
  17320.    case 'C':                /* show only those in include list */               
  17321.               sprintf(temphdr," %s ",header_name);                              
  17322.               if (strstr(np->nnrfcinc,temphdr)) suppress = FALSE;               
  17323.               else                              suppress = TRUE;                
  17324.               break;                                                            
  17325.    case 'D':                /* show none */                                     
  17326.               suppress = TRUE;                                                  
  17327.               break;                                                            
  17328.  }                                                                              
  17329.                                                                                 
  17330.  if (suppress) {                                                                
  17331.    if (tp->text_length >= 0) {                                                  
  17332.      tp->text_length |= 0x8000;    /* force sign bit negative */                
  17333.      ap->thdr.text_line_count--;                                                
  17334.    }                                                                            
  17335.  }                                                                              
  17336.  else {                                                                         
  17337.    if (tp->text_length < 0) {                                                   
  17338.      tp->text_length &= 0x7fff;    /* force sign bit positive */                
  17339.      ap->thdr.text_line_count++;                                                
  17340.    }                                                                            
  17341.  }                                                                              
  17342.                                                                                 
  17343.  return;                                                                        
  17344. }                                                                               
  17345.                                                                                 
  17346. /****** Apply header suppression.  ***********************************/         
  17347.                                                                                 
  17348. static void                                                                     
  17349. apply_header_suppression(np,ap)                                                 
  17350. Rstruc nncb         *np;                                                        
  17351. Rstruc newsarticle  *ap;                                                        
  17352. {                                                                               
  17353.  struct textline     *tp;                                                       
  17354.  struct texthdr      *thp;                                                      
  17355.  char                *cp;                                                       
  17356.  char                *colonp;                                                   
  17357.  int                  header_index;                                             
  17358.  char                 header_name[INTERNET_SIZE];                               
  17359.                                                                                 
  17360.  thp = &ap->thdr;                                                               
  17361.  strcpy(header_name,"");                                                        
  17362.  for (tp=thp->first_text_line; tp; tp=tp->next) {                               
  17363.    if (tp->text[0] == '\0') break;                                              
  17364.    if (tp->text[0] == ' ' ||                                                    
  17365.        tp->text[0] == '\t') {                                                   
  17366.      cp = tp->text + strspn(tp->text," \t");                                    
  17367.      if (*cp == '\0') break;                                                    
  17368.    }                                                                            
  17369.    else {                                                                       
  17370.      header_index = 0;                                                          
  17371.      colonp = strchr(tp->text,':');                                             
  17372.      if (!colonp) break;                                                        
  17373.      strcpy(header_name,"");                                                    
  17374.      for (cp = tp->text;cp<colonp;cp++) {                                       
  17375.        header_name[header_index++] = toupper(*cp);                              
  17376.      }                                                                          
  17377.      header_name[header_index] = '\0';                                          
  17378.    }                                                                            
  17379.    if (*header_name) {                                                          
  17380.       maybe_suppress_header_line(np,ap,tp,header_name);                         
  17381.    }                                                                            
  17382.  }                                                                              
  17383.                                                                                 
  17384.  thp->text_body_line = tp;                                                      
  17385.                                                                                 
  17386.  return;                                                                        
  17387. }                                                                               
  17388.                                                                                 
  17389. /****** Pick article before processing. ******************************/         
  17390.                                                                                 
  17391. Bool                                                                            
  17392. NNMpick(np,ap)                                                                  
  17393. Rstruc nncb          *np;                                                       
  17394. Rstruc newsarticle   *ap;                                                       
  17395. {                                                                               
  17396.  Rstruc newsgroup    *gp;                                                       
  17397.  char                *lp;                                                       
  17398.  enum article_action  bad_status        = ERROR;                                
  17399.  Bool                 retval            = TRUE;                                 
  17400.  Bool                 retrieve_header   = FALSE;                                
  17401.  Bool                 retrieve_body     = FALSE;                                
  17402.                                                                                 
  17403.  np->another_article = NULL;                                                    
  17404.                                                                                 
  17405.  gp = np->current_newsgroup;                                                    
  17406.                                                                                 
  17407.  if (gp == NULL) {                                                              
  17408.    CRIT1("No current newsgroup.  This should never happen.");                   
  17409.    return FALSE;                                                                
  17410.  }                                                                              
  17411.                                                                                 
  17412.  if (V_LENGTH(gp) < ap->number) {                                               
  17413.    fprintf(stderr,"Article vector too short, %d < %d\n",                        
  17414.                   V_LENGTH(gp),ap->number);                                     
  17415.    return FALSE;                                                                
  17416.  }                                                                              
  17417.                                                                                 
  17418.  if (NoSuchArticle(ap)) {                                                       
  17419.    ERR4("Article %d of %s does not exist in server %s.",                        
  17420.         ap->number, gp->name, np->nnserver);                                    
  17421.    retval = FALSE;                                                              
  17422.  }                                                                              
  17423.  else if (ArticleAbsent(ap)) {                                                  
  17424.    ERR4("Article %d of %s was not retrieved by server %s.",                     
  17425.         ap->number, gp->name, np->nnserver);                                    
  17426.    retval = FALSE;                                                              
  17427.  }                                                                              
  17428.  else if (ArticleError(ap)) {                                                   
  17429.    ERR4("Error getting article %d of %s from server %s.",                       
  17430.         ap->number, gp->name, np->nnserver);                                    
  17431.    retval = FALSE;                                                              
  17432.  }                                                                              
  17433.  else {                                                                         
  17434.    retrieve_header = !ArticleHeadRetrieved(ap);                                 
  17435.    retrieve_body   = !ArticleBodyRetrieved(ap);                                 
  17436.  }                                                                              
  17437.                                                                                 
  17438.  if (retrieve_header || retrieve_body) {                                        
  17439.                                                                                 
  17440.    if (!NNMestng(np,NULL)) {           /* Establish newsgroup */                
  17441.      SetGroupError(gp);                                                         
  17442.      OffGroupSelected(gp);                                                      
  17443.      OffGroupRetrieved(gp);                                                     
  17444.      return FALSE;                                                              
  17445.    }                                                                            
  17446.                                                                                 
  17447.    if (retrieve_header) {                                                       
  17448.      if (!NNMrarh(np,gp,ap,FALSE,NULL)) { /* Retrieve article header */         
  17449.        ERR4("Article %d of %s could not be retrieved from server %s.",          
  17450.             ap->number, gp->name, np->nnserver);                                
  17451.        ap->action = MISSING;                                                    
  17452.        return FALSE;                                                            
  17453.      }                                                                          
  17454.    }                                                                            
  17455.                                                                                 
  17456.    sprintf(np->nntp_command,"BODY %d",ap->number);                              
  17457.    if (!NNMsockt(np))      return FALSE; /* Send socket cmd to server*/         
  17458.    if (!NNMgsrvl(np,&lp))  return FALSE; /* Get server line */                  
  17459.    switch(np->nntp_message_num) {                                               
  17460.      case 220:       /* article retrieved - head and body follow    */          
  17461.                break;                                                           
  17462.      case 221:       /* article retrieved - head follows            */          
  17463.                break;                                                           
  17464.      case 222:       /* article retrieved - body follows            */          
  17465.                break;                                                           
  17466.      case 423:       /* no such article number in this group        */          
  17467.                ERR4("Article %d of %s is missing from server %s.",              
  17468.                     ap->number, gp->name, np->nnserver);                        
  17469.                bad_status = MISSING;                                            
  17470.                retval = FALSE;                                                  
  17471.                break;                                                           
  17472.      case 430:       /* no such article found                       */          
  17473.                ERR4("Article %d of %s could not be found by server %s.",        
  17474.                     ap->number, gp->name, np->nnserver);                        
  17475.                bad_status = MISSING;                                            
  17476.                retval = FALSE;                                                  
  17477.                break;                                                           
  17478.      case 223:       /* article retrieved - request text separately */          
  17479.      case 412:       /* no newsgroup has been selected              */          
  17480.      case 420:       /* no current article has been selected        */          
  17481.      default:  NNMrperr(np);      /* Report protocol error */                   
  17482.                retval = FALSE;                                                  
  17483.                break;                                                           
  17484.    }                                                                            
  17485.  }                                                                              
  17486.                                                                                 
  17487.  if (retval == FALSE) {                                                         
  17488.    ap->action = bad_status;                                                     
  17489.    return FALSE;                                                                
  17490.  }                                                                              
  17491.                                                                                 
  17492.  SetArticleRetrieved(ap);                                                       
  17493.  ap->action = NO_ACTION;                                                        
  17494.                                                                                 
  17495.  if (retrieve_body) {                                                           
  17496.    if (!NNMouttx(np," ",ap)) return FALSE;    /* output text line */            
  17497.    collect_text(np,ap);                                                         
  17498.  }                                                                              
  17499.                                                                                 
  17500.  apply_header_suppression(np,ap);                                               
  17501.                                                                                 
  17502.  return TRUE;                                                                   
  17503. }                                                                               
  17504.                                                                                 
  17505. ./   ADD NAME=NNMPMSG,SSI=01160059                                              
  17506.                                                                                 
  17507.  /********************************************************************/         
  17508.  /*                                                                  */         
  17509.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  17510.  /*                                                                  */         
  17511.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  17512.  /* including the implied warranties of merchantability and fitness, */         
  17513.  /* are expressly denied.                                            */         
  17514.  /*                                                                  */         
  17515.  /* Provided this copyright notice is included, this software may    */         
  17516.  /* be freely distributed and not offered for sale.                  */         
  17517.  /*                                                                  */         
  17518.  /* Changes or modifications may be made and used only by the maker  */         
  17519.  /* of same, and not further distributed.  Such modifications should */         
  17520.  /* be mailed to the author for consideration for addition to the    */         
  17521.  /* software and incorporation in subsequent releases.               */         
  17522.  /*                                                                  */         
  17523.  /********************************************************************/         
  17524.                                                                                 
  17525. #define  SUPPRESS_V_DECLARATION                                                 
  17526. #pragma  csect(code,  "NN@PMSG ")                                               
  17527. #pragma  csect(static,"NN$PMSG ")                                               
  17528. #include "nn.h"                                                                 
  17529.                                                                                 
  17530. /****** Set an ISPF message, or write to SYSOUT if batch mode. *******/         
  17531.                                                                                 
  17532. void                                                                            
  17533. NNMpmsg(np,msgtype,msghelp,msgformat) /* also ... for sprintf args */           
  17534. Rstruc nncb *np;                                                                
  17535. int          msgtype;                                                           
  17536. char        *msghelp;                                                           
  17537. char        *msgformat;                                                         
  17538. {                                                                               
  17539.  va_list     argp;                                                              
  17540.  char       *cp;                                                                
  17541.  char        zerrsm    [25];                                                    
  17542.  char        zerrhm     [9];                                                    
  17543.  char        zerralrm   [4];                                                    
  17544.  char        zerrlm    [73];                                                    
  17545.  char        buf      [257];                                                    
  17546.                                                                                 
  17547.  va_start(argp,msgformat);                                                      
  17548.  vsprintf(buf,msgformat,argp);                                                  
  17549.  va_end(argp);                                                                  
  17550.                                                                                 
  17551.  cp = strchr(buf,';');                                                          
  17552.  if (cp) {                                                                      
  17553.   *cp = '\0';                                                                   
  17554.   strncpy(zerrsm,buf, sizeof(zerrsm));                                          
  17555.   strncpy(zerrlm,cp+1,sizeof(zerrlm));                                          
  17556.  }                                                                              
  17557.  else {                                                                         
  17558.   strcpy(zerrsm,"");                                                            
  17559.   strncpy(zerrlm,buf,sizeof(zerrlm));                                           
  17560.  }                                                                              
  17561.                                                                                 
  17562.  zerrsm[sizeof(zerrsm)-1] = '\0';                                               
  17563.  zerrlm[sizeof(zerrlm)-1] = '\0';                                               
  17564.                                                                                 
  17565.  if (msghelp) strcpy(zerrhm, msghelp);                                          
  17566.  else         strcpy(zerrhm, "*"    );                                          
  17567.                                                                                 
  17568.  switch (msgtype) {                                                             
  17569.    case NOTIFY_MSG:    strcpy(zerralrm,"NO "); break;                           
  17570.    case WARNING_MSG:                                                            
  17571.    case CRITICAL_MSG:                                                           
  17572.    default:            strcpy(zerralrm,"YES"); break;                           
  17573.  }                                                                              
  17574.                                                                                 
  17575.  if (np->batch_mode) {                                                          
  17576.   fprintf(np->batch_outfile,"%s: %s\n", zerrsm, zerrlm);                        
  17577.   return;                                                                       
  17578.  }                                                                              
  17579.                                                                                 
  17580.  (void)NNMivput(np,"ZERRSM ",  zerrsm,   -1);                                   
  17581.  (void)NNMivput(np,"ZERRLM ",  zerrlm,   -1);                                   
  17582.  (void)NNMivput(np,"ZERRHM ",  zerrhm,   -1);                                   
  17583.  (void)NNMivput(np,"ZERRALRM ",zerralrm, -1);                                   
  17584.                                                                                 
  17585.  if (np->brifp) {                                                               
  17586.    (void)NNMispf(np,"SETMSG MSG(ISRZ002)");                                     
  17587.  }                                                                              
  17588.  else {                                                                         
  17589.    np->setmsg = TRUE;                                                           
  17590.  }                                                                              
  17591.                                                                                 
  17592.  return;                                                                        
  17593. }                                                                               
  17594.                                                                                 
  17595. ./   ADD NAME=NNMPNG,SSI=010D0019                                               
  17596.                                                                                 
  17597.  /********************************************************************/         
  17598.  /*                                                                  */         
  17599.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  17600.  /*                                                                  */         
  17601.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  17602.  /* including the implied warranties of merchantability and fitness, */         
  17603.  /* are expressly denied.                                            */         
  17604.  /*                                                                  */         
  17605.  /* Provided this copyright notice is included, this software may    */         
  17606.  /* be freely distributed and not offered for sale.                  */         
  17607.  /*                                                                  */         
  17608.  /* Changes or modifications may be made and used only by the maker  */         
  17609.  /* of same, and not further distributed.  Such modifications should */         
  17610.  /* be mailed to the author for consideration for addition to the    */         
  17611.  /* software and incorporation in subsequent releases.               */         
  17612.  /*                                                                  */         
  17613.  /********************************************************************/         
  17614.                                                                                 
  17615. #pragma  csect(code,  "NN@PNG  ")                                               
  17616. #pragma  csect(static,"NN$PNG  ")                                               
  17617. #include "nn.h"                                                                 
  17618.                                                                                 
  17619. /****** Pick newsgroup. **********************************************/         
  17620.                                                                                 
  17621. Bool                                                                            
  17622. NNMpng(np,gp)                                                                   
  17623. Rstruc nncb          *np;                                                       
  17624. Rstruc newsgroup     *gp;                                                       
  17625. {                                                                               
  17626.  Rstruc newsgroup    *gp1;                                                      
  17627.  Bool                 result;                                                   
  17628.                                                                                 
  17629.  result = TRUE;                                                                 
  17630.                                                                                 
  17631.  np->current_newsgroup  = gp;                                                   
  17632.  np->newsgroup_selected = FALSE;                                                
  17633.                                                                                 
  17634.  if (!np->batch_mode) {                                                         
  17635.    (void)NNMivput(np,"NNGROUP ",gp->name,-1);                                   
  17636.  }                                                                              
  17637.                                                                                 
  17638.  np->newsgroup_not_found = FALSE;                                               
  17639.                                                                                 
  17640.  if (gp->first_article == NULL) gp1 = do_newsgroup_by_address(np,gp);           
  17641.  else                           gp1 = gp;                                       
  17642.                                                                                 
  17643.  if (np->newsgroup_not_found) {                                                 
  17644.    SetNoSuchGroup(gp);                                                          
  17645.    gp->real_article_count = 0;                                                  
  17646.    gp->real_unread_count  = 0;                                                  
  17647.    result = FALSE;                                                              
  17648.  }                                                                              
  17649.  else if (gp1 == NULL)         result = FALSE;                                  
  17650.  else if (!NNMvar(np,gp))      result = FALSE;  /* View articles */             
  17651.                                                                                 
  17652.  np->current_newsgroup = NULL;                                                  
  17653.  np->newsgroup_selected = FALSE;                                                
  17654.                                                                                 
  17655.  strcpy(np->nngroup, gp->name);  /* hack to position newsgroup display*/        
  17656.                                                                                 
  17657.  return result;                                                                 
  17658. }                                                                               
  17659.                                                                                 
  17660. ./   ADD NAME=NNMPNRL,SSI=01090043                                              
  17661.                                                                                 
  17662.  /********************************************************************/         
  17663.  /*                                                                  */         
  17664.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  17665.  /*                                                                  */         
  17666.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  17667.  /* including the implied warranties of merchantability and fitness, */         
  17668.  /* are expressly denied.                                            */         
  17669.  /*                                                                  */         
  17670.  /* Provided this copyright notice is included, this software may    */         
  17671.  /* be freely distributed and not offered for sale.                  */         
  17672.  /*                                                                  */         
  17673.  /* Changes or modifications may be made and used only by the maker  */         
  17674.  /* of same, and not further distributed.  Such modifications should */         
  17675.  /* be mailed to the author for consideration for addition to the    */         
  17676.  /* software and incorporation in subsequent releases.               */         
  17677.  /*                                                                  */         
  17678.  /********************************************************************/         
  17679.                                                                                 
  17680. #pragma  csect(code,  "NN@PNRL ")                                               
  17681. #pragma  csect(static,"NN$PNRL ")                                               
  17682. #include "nn.h"                                                                 
  17683.                                                                                 
  17684. /****** Parse NEWSRC line. *******************************************/         
  17685.                                                                                 
  17686. void                                                                            
  17687. NNMpnrl(np,gp)                                                                  
  17688. Rstruc nncb         *np;                                                        
  17689. Rstruc newsgroup    *gp;                                                        
  17690. {                                                                               
  17691.  register char      *nlp                  = gp->saved_newsrc_line;              
  17692.  int                 newsrc_number1;                                            
  17693.  int                 newsrc_number2;                                            
  17694.  int                 newsrc_scan_count    = 0;                                  
  17695.                                                                                 
  17696.  if (np->debug_file) {                                                          
  17697.    fprintf(np->debug_file, "NNMpnrl: status of %s is 0x%2.2x\n",                
  17698.                            gp->name, gp->status);                               
  17699.  }                                                                              
  17700.                                                                                 
  17701.  if (!nlp) {                                                                    
  17702.    if (np->debug_file)                                                          
  17703.       fprintf(np->debug_file, "NNMpnrl: no saved newsrc line for %s\n",         
  17704.                               gp->name);                                        
  17705.    return;                                                                      
  17706.  }                                                                              
  17707.                                                                                 
  17708.  /* get next number thing */                                                    
  17709.                                                                                 
  17710.  while (*nlp) {                                                                 
  17711.                                                                                 
  17712.    while (*nlp && isspace(*nlp)) nlp++;                                         
  17713.                                                                                 
  17714.    switch (*nlp) {                                                              
  17715.      case '\0': newsrc_number1 = 1;                                             
  17716.                 newsrc_number2 = 0;                                             
  17717.                 break;                                                          
  17718.      case '<':  sscanf(nlp," <%d %n",    &newsrc_number2,                       
  17719.                                          &newsrc_scan_count);                   
  17720.                 newsrc_number1 = 1;                                             
  17721.                 nlp += newsrc_scan_count;                                       
  17722.                 break;                                                          
  17723.      case '|':  sscanf(nlp," |%d=%d %n", &newsrc_number1,                       
  17724.                                          &newsrc_number2,                       
  17725.                                          &newsrc_scan_count);                   
  17726.                 nlp += newsrc_scan_count;                                       
  17727.                 break;                                                          
  17728.      case '{':  nlp = strchr(++nlp,'}');                                        
  17729.                 if (nlp) nlp++;                                                 
  17730.                 break;                                                          
  17731.      case '#':  nlp = strchr(++nlp,'#');                                        
  17732.                 if (nlp) nlp++;                                                 
  17733.                 break;                                                          
  17734.      default:   sscanf(nlp," %d %n",     &newsrc_number1,                       
  17735.                                          &newsrc_scan_count);                   
  17736.                 newsrc_number2 = newsrc_number1;                                
  17737.                 nlp += newsrc_scan_count;                                       
  17738.                 break;                                                          
  17739.    }                                                                            
  17740.                                                                                 
  17741.    for (;newsrc_number1 <= newsrc_number2; newsrc_number1++) {                  
  17742.                                                                                 
  17743.      /* we used to check newsrc_topnum here, but that isn't passed, */          
  17744.      /* so now we use gp->article_vector_len.  Hope that's OK       */          
  17745.                                                                                 
  17746.      if (newsrc_number1 <= V_LENGTH(gp)) {                                      
  17747.        V_STATUS(gp,newsrc_number1) = V_READ;                                    
  17748.      }                                                                          
  17749.    }                                                                            
  17750.  }                                                                              
  17751.                                                                                 
  17752.  /* We're finished parsing the newsrc line, so free it. */                      
  17753.                                                                                 
  17754.  if (gp->saved_newsrc_line != gp->saved_newsrc_data) {                          
  17755.    FREEMAIN(gp->saved_newsrc_line,"parsed newsrc line");                        
  17756.  }                                                                              
  17757.                                                                                 
  17758.  gp->saved_newsrc_line = NULL;  /* bug fix 10/15/91 from Dale (SAS) */          
  17759.  gp->saved_newsrc_data[0] = '\0';                                               
  17760.                                                                                 
  17761.  return;                                                                        
  17762. }                                                                               
  17763.                                                                                 
  17764. ./   ADD NAME=NNMPTX,SSI=01020024                                               
  17765.                                                                                 
  17766.  /********************************************************************/         
  17767.  /*                                                                  */         
  17768.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  17769.  /*                                                                  */         
  17770.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  17771.  /* including the implied warranties of merchantability and fitness, */         
  17772.  /* are expressly denied.                                            */         
  17773.  /*                                                                  */         
  17774.  /* Provided this copyright notice is included, this software may    */         
  17775.  /* be freely distributed and not offered for sale.                  */         
  17776.  /*                                                                  */         
  17777.  /* Changes or modifications may be made and used only by the maker  */         
  17778.  /* of same, and not further distributed.  Such modifications should */         
  17779.  /* be mailed to the author for consideration for addition to the    */         
  17780.  /* software and incorporation in subsequent releases.               */         
  17781.  /*                                                                  */         
  17782.  /********************************************************************/         
  17783.                                                                                 
  17784. #pragma  csect(code,  "NN@PTX  ")                                               
  17785. #pragma  csect(static,"NN$PTX  ")                                               
  17786. #include "nn.h"                                                                 
  17787.                                                                                 
  17788. /****** Print the lines of server text. ******************************/         
  17789.                                                                                 
  17790. void                                                                            
  17791. NNMptx(np,ap)                                                                   
  17792. Rstruc nncb         *np;                                                        
  17793. Rstruc newsarticle  *ap;                                                        
  17794. {                                                                               
  17795.  FILE               *pfp;                                                       
  17796.  struct texthdr     *thp;                                                       
  17797.  struct textline    *tp;                                                        
  17798.                                                                                 
  17799.  /* If article is not specified, use main nncb, else article's text */          
  17800.                                                                                 
  17801.  thp = (ap ? &ap->thdr : &np->thdr);                                            
  17802.                                                                                 
  17803.  pfp = stdout;                                                                  
  17804.                                                                                 
  17805.  /* Article must be specified (cannot be null). */                              
  17806.                                                                                 
  17807.  for (tp=thp->first_text_line;tp;tp=tp->next) {                                 
  17808.    if (tp->text_length >= 0) {                                                  
  17809.      char *p = tp->tab_expanded_text;                                           
  17810.      while (*p) {                                                               
  17811.        if isprint(*p) fprintf(pfp,"%c",*p);                                     
  17812.        else fprintf(pfp,"?");                                                   
  17813.        p++;                                                                     
  17814.      }                                                                          
  17815.      fprintf(pfp,"\n");                                                         
  17816.    }                                                                            
  17817.  }                                                                              
  17818.  fprintf(pfp,"\n");                                                             
  17819.                                                                                 
  17820.  return;                                                                        
  17821.                                                                                 
  17822. }                                                                               
  17823.                                                                                 
  17824. ./   ADD NAME=NNMQAR,SSI=010B0037                                               
  17825.                                                                                 
  17826.  /********************************************************************/         
  17827.  /*                                                                  */         
  17828.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  17829.  /*                                                                  */         
  17830.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  17831.  /* including the implied warranties of merchantability and fitness, */         
  17832.  /* are expressly denied.                                            */         
  17833.  /*                                                                  */         
  17834.  /* Provided this copyright notice is included, this software may    */         
  17835.  /* be freely distributed and not offered for sale.                  */         
  17836.  /*                                                                  */         
  17837.  /* Changes or modifications may be made and used only by the maker  */         
  17838.  /* of same, and not further distributed.  Such modifications should */         
  17839.  /* be mailed to the author for consideration for addition to the    */         
  17840.  /* software and incorporation in subsequent releases.               */         
  17841.  /*                                                                  */         
  17842.  /********************************************************************/         
  17843.                                                                                 
  17844. #pragma  csect(code,  "NN@QAR  ")                                               
  17845. #pragma  csect(static,"NN$QAR  ")                                               
  17846. #include "nn.h"                                                                 
  17847.                                                                                 
  17848. /****** Query article. ***********************************************/         
  17849.                                                                                 
  17850. Bool                                                                            
  17851. NNMqar(np,ap)                                                                   
  17852. Rstruc nncb         *np;                                                        
  17853. Rstruc newsarticle  *ap;                                                        
  17854. {                                                                               
  17855.  Rstruc newsgroup   *gp;                                                        
  17856.                                                                                 
  17857.  gp = np->current_newsgroup;                                                    
  17858.                                                                                 
  17859.  if (gp == NULL) {                                                              
  17860.   CRIT1("No current newsgroup.  This should never happen.");                    
  17861.   return FALSE;                                                                 
  17862.  }                                                                              
  17863.                                                                                 
  17864.  printf("\n");                                                                  
  17865.  printf("status.....................%2.2X\n", ap->status);                      
  17866.  if (NoSuchArticle(ap))        printf(" NoSuchArticle\n"        );              
  17867.  if (ArticleAbsent(ap))        printf(" ArticleAbsent\n"        );              
  17868.  if (ArticleError(ap))         printf(" ArticleError\n"         );              
  17869.  if (ArticleBadData(ap))       printf(" ArticleBadData\n"       );              
  17870.  if (ArticleHeadRetrieved(ap)) printf(" ArticleHeadRetrieved\n" );              
  17871.  if (ArticleBodyRetrieved(ap)) printf(" ArticleBodyRetrieved\n" );              
  17872.  if (ArticleInTable(ap))       printf(" ArticleInTable\n"       );              
  17873.  printf("action.......................");                                       
  17874.  switch (ap->action) {                                                          
  17875.    case NO_ACTION:             printf("NO_ACTION");             break;          
  17876.    case READ:                  printf("READ");                  break;          
  17877.    case RETRIEVED:             printf("RETRIEVED");             break;          
  17878.    case EXTRACTED:             printf("EXTRACTED");             break;          
  17879.    case PRINTED:               printf("PRINTED");               break;          
  17880.    case UNREAD:                printf("UNREAD");                break;          
  17881.    case MISSING:               printf("MISSING");               break;          
  17882.    case ERROR:                 printf("ERROR");                 break;          
  17883.    case CANCELLED:             printf("CANCELLED");             break;          
  17884.    default:                    printf("%d",ap->action);         break;          
  17885.  }                                                                              
  17886.  printf("\n");                                                                  
  17887.  printf("number.......................%d\n",    ap->number);                    
  17888.  printf("from.........................%s\n",    ap->from);                      
  17889.  printf("subject......................%s\n",    ap->subject);                   
  17890.  printf("date.........................%s\n",    ap->date);                      
  17891.  printf("message_id...................%s\n",    ap->message_id);                
  17892.                                                                                 
  17893.  if (ap->csubject)                                                              
  17894.    printf("csubject.....................%s\n",  ap->csubject);                  
  17895.  else                                                                           
  17896.    printf("csubject is NULL\n");                                                
  17897.                                                                                 
  17898.                                                                                 
  17899.  return TRUE;                                                                   
  17900. }                                                                               
  17901.                                                                                 
  17902. ./   ADD NAME=NNMQNG,SSI=010C0000                                               
  17903.                                                                                 
  17904.  /********************************************************************/         
  17905.  /*                                                                  */         
  17906.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  17907.  /*                                                                  */         
  17908.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  17909.  /* including the implied warranties of merchantability and fitness, */         
  17910.  /* are expressly denied.                                            */         
  17911.  /*                                                                  */         
  17912.  /* Provided this copyright notice is included, this software may    */         
  17913.  /* be freely distributed and not offered for sale.                  */         
  17914.  /*                                                                  */         
  17915.  /* Changes or modifications may be made and used only by the maker  */         
  17916.  /* of same, and not further distributed.  Such modifications should */         
  17917.  /* be mailed to the author for consideration for addition to the    */         
  17918.  /* software and incorporation in subsequent releases.               */         
  17919.  /*                                                                  */         
  17920.  /********************************************************************/         
  17921.                                                                                 
  17922. #pragma  csect(code,  "NN@QNG  ")                                               
  17923. #pragma  csect(static,"NN$QNG  ")                                               
  17924. #include "nn.h"                                                                 
  17925.                                                                                 
  17926. /****** Query newsgroup. *********************************************/         
  17927.                                                                                 
  17928. void                                                                            
  17929. NNMqng(np,gp)                                                                   
  17930. Rstruc nncb         *np;                                                        
  17931. Rstruc newsgroup    *gp;                                                        
  17932. {                                                                               
  17933.  int                 anum;                                                      
  17934.                                                                                 
  17935.  if (!gp) return;                                                               
  17936.                                                                                 
  17937.  printf("\n  Struct at %8.8X: Newsgroup '%s'\n\n", gp, gp->name);               
  17938.  printf("next.......................%8.8X\n", gp->next);                        
  17939.  printf("next2......................%8.8X\n", gp->next2);                       
  17940.  printf("fake_article_count.........%d\n",gp->fake_article_count);              
  17941.  printf("real_article_count.........%d\n",gp->real_article_count);              
  17942.  printf("fake_first_article_number..%d\n",                                      
  17943.                                          gp->fake_first_article_number);        
  17944.  printf("real_first_article_number..%d\n",                                      
  17945.                                          gp->real_first_article_number);        
  17946.  printf("fake_last_article_number...%d\n",gp->fake_last_article_number);        
  17947.  printf("real_last_article_number...%d\n",gp->real_last_article_number);        
  17948.  printf("fake_unread_count..........%d\n",gp->fake_unread_count);               
  17949.  printf("real_unread_count..........%d\n",gp->real_unread_count);               
  17950.  printf("registered.................%d\n",gp->registered);                      
  17951.  printf("first_article..............%8.8X\n", gp->first_article);               
  17952.  printf("fake_last_article..........%8.8X\n", gp->fake_last_article);           
  17953.  printf("real_last_article..........%8.8X\n", gp->real_last_article);           
  17954.  printf("article_vector.............%8.8X\n", gp->article_vector);              
  17955.  printf("article_vector_len.........%d\n",    gp->article_vector_len);          
  17956.  printf("saved_newsrc_line..........%8.8X\n", gp->saved_newsrc_line);           
  17957.  printf("saved_newsrc_data..........%s\n",    gp->saved_newsrc_data);           
  17958.  printf("status.....................%2.2X\n", gp->status);                      
  17959.  if (NoSuchGroup(gp))      printf(" NoSuchGroup\n"    );                        
  17960.  if (NewGroup(gp))         printf(" NewGroup\n"       );                        
  17961.  if (GroupFromNewsrc(gp))  printf(" GroupFromNewsrc\n");                        
  17962.  if (GroupListed(gp))      printf(" GroupListed\n"    );                        
  17963.  if (GroupSelected(gp))    printf(" GroupSelected\n"  );                        
  17964.  if (GroupRetrieved(gp))   printf(" GroupRetrieved\n" );                        
  17965.  if (GroupError(gp))       printf(" GroupError\n"     );                        
  17966.  if (GroupInTable(gp))     printf(" GroupInTable\n"   );                        
  17967.  printf("name.......................%s\n",    gp->name);                        
  17968.  if (gp->saved_newsrc_line) {                                                   
  17969.    printf("\nSaved newsrc line follows:\n%s\n\n",                               
  17970.           gp->saved_newsrc_line);                                               
  17971.  }                                                                              
  17972.  printf("Article vector follows:\n");                                           
  17973.  for (anum = 0; anum < gp->article_vector_len; anum++) {                        
  17974.    printf("%c", gp->article_vector[anum]);                                      
  17975.  }                                                                              
  17976.  printf("\n");                                                                  
  17977.                                                                                 
  17978.  return;                                                                        
  17979. }                                                                               
  17980.                                                                                 
  17981. ./   ADD NAME=NNMRAARH,SSI=012F0046                                             
  17982.                                                                                 
  17983.  /********************************************************************/         
  17984.  /*                                                                  */         
  17985.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  17986.  /*                                                                  */         
  17987.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  17988.  /*                                                                  */         
  17989.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  17990.  /* including the implied warranties of merchantability and fitness, */         
  17991.  /* are expressly denied.                                            */         
  17992.  /*                                                                  */         
  17993.  /* Provided this copyright notice is included, this software may    */         
  17994.  /* be freely distributed and not offered for sale.                  */         
  17995.  /*                                                                  */         
  17996.  /* Changes or modifications may be made and used only by the maker  */         
  17997.  /* of same, and not further distributed.  Such modifications should */         
  17998.  /* be mailed to the author for consideration for addition to the    */         
  17999.  /* software and incorporation in subsequent releases.               */         
  18000.  /*                                                                  */         
  18001.  /********************************************************************/         
  18002.                                                                                 
  18003. #pragma  csect(code,  "NN@RAARH")                                               
  18004. #pragma  csect(static,"NN$RAARH")                                               
  18005. #include "nn.h"                                                                 
  18006.                                                                                 
  18007. /****** Get those articles. ******************************************/         
  18008.                                                                                 
  18009. static void                                                                     
  18010. get_those_articles(np,gp,app,vstatus1,vstatus2,cdp)                             
  18011. Rstruc nncb          *np;                                                       
  18012. Rstruc newsgroup     *gp;                                                       
  18013. Rstruc newsarticle  **app;                                                      
  18014. int                   vstatus1;                                                 
  18015. int                   vstatus2;                                                 
  18016. struct countdown     *cdp;                                                      
  18017. {                                                                               
  18018.  VARK                *vp;                                                       
  18019.  int                  anum;                                                     
  18020.                                                                                 
  18021.  for (anum =  gp->fake_last_article_number;                                     
  18022.       anum >= gp->fake_first_article_number;                                    
  18023.       anum--                                 ) {                                
  18024.                                                                                 
  18025.    if (gp->real_article_count >= gp->fake_article_count) break;                 
  18026.    if (*app > gp->fake_last_article) {                                          
  18027.      fprintf(stderr,"News server lied, more articles than estimated\n");        
  18028.      fprintf(stderr,"Not retrieving article %d\n",anum);                        
  18029.      break;                                                                     
  18030.    }                                                                            
  18031.                                                                                 
  18032.    vp = &V_STATUS(gp,anum);                                                     
  18033.    if (*vp != vstatus1 && *vp != vstatus2) continue;                            
  18034.                                                                                 
  18035.    (*app)->number = anum;                                                       
  18036.                                                                                 
  18037.  /* If bypassing header retrieval ("Z" option),                                 
  18038.   * or article header has already been retrieved,                               
  18039.   * or article was already read, according to newsrc,                           
  18040.   * then don't get the header - assume it is there.                             
  18041.   * (NNMrarh will be called when an article's header is required.)              
  18042.   * Otherwise, get the header now.                                              
  18043.   */                                                                            
  18044.                                                                                 
  18045.    if (*vp == V_MISSING_READ) continue; /* read but dead forever */             
  18046.                                                                                 
  18047.    if (np->bypass_header_retrieval                                              
  18048.     || ArticleHeadRetrieved(*app)                                               
  18049.     || *vp == V_READ                                                            
  18050.     || NNMrarh(np,gp,*app,FALSE,cdp)) {   /* Retrieve article header */         
  18051.      gp->real_article_count++;                                                  
  18052.      if (gp->real_first_article_number == NO_VALUE ||                           
  18053.          gp->real_first_article_number > anum)                                  
  18054.         gp->real_first_article_number = anum;                                   
  18055.      if (gp->real_last_article_number == NO_VALUE ||                            
  18056.          gp->real_last_article_number < anum)                                   
  18057.         gp->real_last_article_number = anum;                                    
  18058.      switch (*vp) {                                                             
  18059.        case V_READ:           (*app)->action = READ;                            
  18060.                               if (NoSuchArticle(*app))                          
  18061.                                   ClearArticleStatus(*app);                     
  18062.                               break;                                            
  18063.        case V_UNREAD:         (*app)->action = UNREAD;                          
  18064.                               if (NoSuchArticle(*app))                          
  18065.                                   ClearArticleStatus(*app);                     
  18066.                               gp->real_unread_count++;                          
  18067.                               break;                                            
  18068.        case V_MISSING_READ:   (*app)->action = READ;                            
  18069.                               *vp = V_READ;                                     
  18070.                               break;                                            
  18071.        case V_MISSING_UNREAD: (*app)->action = UNREAD;                          
  18072.                               gp->real_unread_count++;                          
  18073.                               *vp = V_UNREAD;                                   
  18074.                               break;                                            
  18075.      }                                                                          
  18076.      (*app)++;                                                                  
  18077.    }                                                                            
  18078.    else *vp = V_MISSING_UNREAD;                                                 
  18079.  }                                                                              
  18080.  return;                                                                        
  18081. }                                                                               
  18082.                                                                                 
  18083. /****** Retrieve all article headers. ********************************/         
  18084.                                                                                 
  18085. Bool                                                                            
  18086. NNMraarh(np,gp)                                                                 
  18087. Rstruc nncb          *np;                                                       
  18088. Rstruc newsgroup     *gp;                                                       
  18089. {                                                                               
  18090.  struct newsarticle  *ap;                                                       
  18091.  int                  anum;                                                     
  18092.  int                  est_first_article_number;                                 
  18093.  int                  est_last_article_number;                                  
  18094.  int                  est_max_article_count;                                    
  18095.  Bool                 est_discrepancy = FALSE;                                  
  18096.  struct countdown     cd;                                                       
  18097.                                                                                 
  18098.  cd.do_update = (np->updatefreq >= 0);                                          
  18099.  cd.done      = 0;                                                              
  18100.  cd.to_do     = gp->fake_unread_count;                                          
  18101.                                                                                 
  18102.  /* If news articles were already retrieved, don't do it again */               
  18103.  /* unless the newsgroup was changed (new articles came in).   */               
  18104.                                                                                 
  18105.  if (GroupRetrieved(gp)) {                                                      
  18106.    if (gp->fake_last_article_number >= gp->real_last_article_number)            
  18107.       return TRUE;                                                              
  18108.  }                                                                              
  18109.                                                                                 
  18110.  /* Allocate memory to hold all the articles for this newsgroup. */             
  18111.                                                                                 
  18112.  gp->real_article_count = 0;                                                    
  18113.  gp->real_unread_count  = 0;                                                    
  18114.                                                                                 
  18115.  if (!GroupSelected(gp)) {                                                      
  18116.    if (!NNMestng(np,gp->name)) return FALSE; /* Establish newsgroup */          
  18117.    /* Extract the number of articles. */                                        
  18118.    if (3 != sscanf(np->nntp_message_text,"%d %d %d",                            
  18119.                                          &gp->fake_article_count,               
  18120.                                          &est_first_article_number,             
  18121.                                          &est_last_article_number)) {           
  18122.      NNMrbfm(np);   /* Report bad format message */                             
  18123.      return FALSE;                                                              
  18124.    }                                                                            
  18125.                                                                                 
  18126.    SetGroupSelected(gp);                                                        
  18127.                                                                                 
  18128.    if (gp->fake_first_article_number != NO_VALUE &&                             
  18129.        gp->fake_first_article_number != est_first_article_number) {             
  18130.      est_discrepancy = TRUE;                                                    
  18131.      gp->fake_first_article_number = est_first_article_number;                  
  18132.    }                                                                            
  18133.    if (gp->fake_last_article_number != NO_VALUE &&                              
  18134.        gp->fake_last_article_number != est_last_article_number) {               
  18135.      est_discrepancy = TRUE;                                                    
  18136.      gp->fake_last_article_number = est_last_article_number;                    
  18137.    }                                                                            
  18138.    if (est_discrepancy) {                                                       
  18139.      est_max_article_count = est_last_article_number                            
  18140.                              - est_first_article_number + 1;                    
  18141.                                                                                 
  18142.      if (gp->fake_article_count != NO_VALUE &&                                  
  18143.          est_max_article_count < gp->fake_article_count) {                      
  18144.        fprintf(stderr,"%s: server said %d articles, newsgroup max %d\n",        
  18145.                       gp->name,                                                 
  18146.                       gp->fake_article_count,                                   
  18147.                       est_max_article_count);                                   
  18148.        gp->fake_article_count = est_max_article_count;                          
  18149.      }                                                                          
  18150.    }                                                                            
  18151.  }                                                                              
  18152.                                                                                 
  18153.  /* assert GroupSelected(gp); */                                                
  18154.                                                                                 
  18155.  if (!NNMallav(np,gp)) return FALSE;   /* Allocate article vector */            
  18156.                                                                                 
  18157.  if (gp->fake_article_count == 0) {                                             
  18158.    ERR2("No articles in newsgroup %s.", gp->name);                              
  18159.    gp->real_unread_count = 0;                                                   
  18160.    return TRUE;                                                                 
  18161.  }                                                                              
  18162.                                                                                 
  18163.  if (np->debug_file) fprintf(np->debug_file,                                    
  18164.                       "NNMraarh: getting array of %d articles for %s\n",        
  18165.                       gp->fake_article_count, gp->name);                        
  18166.                                                                                 
  18167.  FREEMAIN(gp->first_article,"previous news articles");                          
  18168.                                                                                 
  18169.  GETMAIN(gp->first_article, struct newsarticle, gp->fake_article_count,         
  18170.                                                 "news articles");               
  18171.                                                                                 
  18172.  if (gp->first_article == NULL) {                                               
  18173.    ERR1("There is not enough virtual storage to retrieve articles.");           
  18174.    return FALSE;                                                                
  18175.  }                                                                              
  18176.                                                                                 
  18177.  gp->fake_last_article = gp->first_article+gp->fake_article_count-1;            
  18178.  gp->real_last_article = NULL;                                                  
  18179.                                                                                 
  18180.  /* Clear all allocated news articles. */                                       
  18181.                                                                                 
  18182.  for (ap=gp->first_article, anum=gp->fake_first_article_number;                 
  18183.       ap<=gp->fake_last_article;                                                
  18184.       ap++, anum++) {                                                           
  18185.    ClearArticleStatus(ap);                                                      
  18186.    if (anum > gp->fake_last_article_number) {                                   
  18187.      SetNoSuchArticle(ap);                                                      
  18188.      ap->action = MISSING;                                                      
  18189.    }                                                                            
  18190.    else {                                                                       
  18191.      ap->action = NO_ACTION;                                                    
  18192.      gp->real_last_article = ap;                                                
  18193.    }                                                                            
  18194.    ap->number      = NO_VALUE;                                                  
  18195.    ap->from        = "";                                                        
  18196.    ap->subject     = "";                                                        
  18197.    ap->date        = "";                                                        
  18198.    ap->message_id  = "";                                                        
  18199.    ap->csubject    = NULL;                                                      
  18200.    ap->thdr.first_text_line = NULL;                                             
  18201.    NNMclrtx(np,ap);                  /* Clear text */                           
  18202.  }                                                                              
  18203.                                                                                 
  18204.  SetGroupRetrieved(gp);                                                         
  18205.                                                                                 
  18206.  /* Retrieve article titles from the server.  Since the count is only           
  18207.     an estimation (although it is guaranteed to be at least as large            
  18208.     as the actual number of articles), start from the lowest number and         
  18209.     get articles for higher and higher numbers until no article is              
  18210.     found.  Stop at the highest number.  Or should we start from the            
  18211.     highest number and go lower until the lowest number? */                     
  18212.                                                                                 
  18213.  if (gp->real_last_article == NULL) {                                           
  18214.    ERR2("No articles in newsgroup %s.", gp->name);                              
  18215.    gp->real_unread_count = 0;                                                   
  18216.    return FALSE;                                                                
  18217.  }                                                                              
  18218.                                                                                 
  18219.  if (!np->bypass_header_retrieval) {                                            
  18220.    if (!np->batch_mode) {                                                       
  18221.      (void)NNMispf(np,"CONTROL DISPLAY LOCK");                                  
  18222.      (void)NNMispf(np,"DISPLAY PANEL(NNMLARTS)");                               
  18223.    }                                                                            
  18224.  }                                                                              
  18225.                                                                                 
  18226.  ap = gp->first_article;                                                        
  18227.                                                                                 
  18228.  get_those_articles(np,gp,&ap,V_UNREAD, V_MISSING_UNREAD,&cd);                  
  18229.  get_those_articles(np,gp,&ap,V_READ,   V_MISSING_READ,  &cd);                  
  18230.                                                                                 
  18231.  NNMsort(np,gp);                                                                
  18232.                                                                                 
  18233.  /* gp->fake_first_article_number = gp->real_first_article_number; */           
  18234.  if (gp->real_last_article_number > gp->fake_last_article_number)               
  18235.      gp->fake_last_article_number = gp->real_last_article_number;               
  18236.  gp->fake_article_count = gp->real_article_count;                               
  18237.  gp->fake_unread_count  = gp->real_unread_count;                                
  18238.                                                                                 
  18239.  if (gp->real_article_count == 0) {                                             
  18240.    ERR2("No articles in newsgroup %s.", gp->name);                              
  18241.    return FALSE;                                                                
  18242.  }                                                                              
  18243.                                                                                 
  18244.  return TRUE;                                                                   
  18245. }                                                                               
  18246.                                                                                 
  18247. ./   ADD NAME=NNMRARH,SSI=01290051                                              
  18248.                                                                                 
  18249.  /********************************************************************/         
  18250.  /*                                                                  */         
  18251.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  18252.  /*                                                                  */         
  18253.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  18254.  /*                                                                  */         
  18255.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  18256.  /* including the implied warranties of merchantability and fitness, */         
  18257.  /* are expressly denied.                                            */         
  18258.  /*                                                                  */         
  18259.  /* Provided this copyright notice is included, this software may    */         
  18260.  /* be freely distributed and not offered for sale.                  */         
  18261.  /*                                                                  */         
  18262.  /* Changes or modifications may be made and used only by the maker  */         
  18263.  /* of same, and not further distributed.  Such modifications should */         
  18264.  /* be mailed to the author for consideration for addition to the    */         
  18265.  /* software and incorporation in subsequent releases.               */         
  18266.  /*                                                                  */         
  18267.  /********************************************************************/         
  18268.                                                                                 
  18269. #pragma  csect(code,  "NN@RARH ")                                               
  18270. #pragma  csect(static,"NN$RARH ")                                               
  18271. #include "nn.h"                                                                 
  18272.                                                                                 
  18273. /****** Retrieve article header. *************************************/         
  18274.                                                                                 
  18275. Bool                                                                            
  18276. NNMrarh(np,gp,ap,adjp,cdp)                                                      
  18277. Rstruc nncb          *np;                                                       
  18278. Rstruc newsgroup     *gp;                                                       
  18279. Rstruc newsarticle   *ap;                                                       
  18280. Fool                  adjp;                                                     
  18281. struct countdown     *cdp;                                                      
  18282. {                                                                               
  18283.  Rstruc newsarticle  *ap1;                                                      
  18284.  Rstruc newsarticle  *ap2;                                                      
  18285.  char                *lp;                                                       
  18286.  char                *cp;                                                       
  18287.  VARK                *vp;                                                       
  18288.  struct textline     *tp;                                                       
  18289.  int                  nextnumber;                                               
  18290.  int                  header_index;                                             
  18291.  char                 header_name[INTERNET_SIZE];                               
  18292.                                                                                 
  18293.  np->article_error_found = FALSE;                                               
  18294.                                                                                 
  18295.  /* If article has already been retrieved, do nothing. */                       
  18296.                                                                                 
  18297.  if (ArticleHeadRetrieved(ap)) return TRUE;                                     
  18298.                                                                                 
  18299.  ClearArticleStatus(ap);                                                        
  18300.                                                                                 
  18301.  if (!NNMestng(np,NULL)) {                 /* Establish newsgroup */            
  18302.    SetArticleError(ap);                                                         
  18303.    ap->action = ERROR;                                                          
  18304.    return FALSE;                                                                
  18305.  }                                                                              
  18306.                                                                                 
  18307.  tp = NULL;                                                                     
  18308.                                                                                 
  18309.  /* If user asked for screen updates, do them here. */                          
  18310.                                                                                 
  18311.  NNMupdt(np,cdp,"NNMLART2");                                                    
  18312.                                                                                 
  18313.  /* Ask for the head of the article by number. */                               
  18314.  /* (Is it better to ask by message-id? Dunno) */                               
  18315.                                                                                 
  18316.  sprintf(np->nntp_command,"HEAD %d",ap->number);                                
  18317.  if (!NNMsockt(np)) return FALSE;  /* Send socket command to server */          
  18318.                                                                                 
  18319.  if (NNMgsrvl(np,&lp)) {           /* Get server line */                        
  18320.    switch (np->nntp_message_num) {                                              
  18321.      case 221:          /* article retrieved, head follows         */           
  18322.                SetArticleHeadRetrieved(ap);                                     
  18323.                break;                                                           
  18324.      case 423:          /*    no such article number in this group */           
  18325.                SetNoSuchArticle(ap);                                            
  18326.                break;                                                           
  18327.      case 430:          /*    no such article found                */           
  18328.                SetArticleAbsent(ap);                                            
  18329.                break;                                                           
  18330.      default:                                                                   
  18331.                SetArticleError(ap);                                             
  18332.                NNMrperr(np);        /* Report protocol error */                 
  18333.                break;                                                           
  18334.    }                                                                            
  18335.  }                                                                              
  18336.                                                                                 
  18337.  if (!ArticleHeadRetrieved(ap)) {                                               
  18338.    /* squeeze the article out of the table and tell all comers to               
  18339.     * start over if necessary.                                                  
  18340.     *                                                                           
  18341.     * Do this only when adjp = TRUE, i.e. it is necessary to adjust             
  18342.     * the article array.                                                        
  18343.     *                                                                           
  18344.     * this code will only work if gp->real etc. had not been changed            
  18345.     * fake_first should be the original from the NNTP GROUP                     
  18346.     * real_first should be the one we assumed was true                          
  18347.     *                                                                           
  18348.     */                                                                          
  18349.    if (adjp && !np->sort_by_subject                                             
  18350.     && gp->real_first_article_number > gp->fake_first_article_number) {         
  18351.      nextnumber = ap->number;                                                   
  18352.      for (ap1 = ap; ap1 > gp->first_article; ap1--) {                           
  18353.        memcpy(ap1, ap1-1, sizeof(struct newsarticle));                          
  18354.        nextnumber = ap1->number;                                                
  18355.      }                                                                          
  18356.      memset(ap1, 0, sizeof(struct newsarticle));                                
  18357.      ClearArticleStatus(ap1);                                                   
  18358.      ap1->action      = NO_ACTION;                                              
  18359.      ap1->number      = nextnumber - 1;                                         
  18360.      ap1->from        = "";                                                     
  18361.      ap1->subject     = "";                                                     
  18362.      ap1->date        = "";                                                     
  18363.      ap1->message_id  = "";                                                     
  18364.      ap1->csubject    = NULL;                                                   
  18365.      ap1->thdr.first_text_line = NULL;                                          
  18366.      NNMclrtx(np,ap1);                  /* Clear text */                        
  18367.      gp->real_first_article_number = ap1->number;                               
  18368.      np->article_error_found = TRUE;                                            
  18369.    }                                                                            
  18370.    else {                                                                       
  18371.      ap->action = ERROR;                                                        
  18372.    }                                                                            
  18373.                                                                                 
  18374.    return FALSE;                                                                
  18375.  }                                                                              
  18376.                                                                                 
  18377.  /* Scan the text for headers and extract the subject and whatever. */          
  18378.                                                                                 
  18379.  np->sending_text = TRUE; /* Stuff following is header text */                  
  18380.                                                                                 
  18381.  for (;;) {                                                                     
  18382.                                                                                 
  18383.    if (!NNMgsrvl(np,&lp))            break;  /* Get server line */              
  18384.    if (lp == NULL)                   break;                                     
  18385.    if (np->server_finished_replying) break;                                     
  18386.    if (!(tp=NNMouttx(np,lp,ap)))     break;  /* Output text line */             
  18387.                                                                                 
  18388.    if (*tp->text == ' '                                                         
  18389.     || *tp->text == '\t')             continue;                                 
  18390.                                                                                 
  18391.    strcpy(header_name,"");                                                      
  18392.    header_index = 0;                                                            
  18393.    for (cp = tp->text;;cp++) {                                                  
  18394.      if (*cp == ':') break;                                                     
  18395.      else if (*cp == '\0' || *cp == ' ' || *cp == '\t') {                       
  18396.        NNMdump(np,"Warning, bad header line",lp,strlen(lp));                    
  18397.        SetArticleBadData(ap);                                                   
  18398.        break;                                                                   
  18399.      }                                                                          
  18400.      else header_name[header_index++] = toupper(*cp);                           
  18401.    }                                                                            
  18402.                                                                                 
  18403.    header_name[header_index] = '\0';                                            
  18404.    while (*++cp && isspace(*cp));                                               
  18405.    if      (EQUAL(header_name,"FROM")) {                                        
  18406.            ap->from = cp;                                                       
  18407.    }                                                                            
  18408.    else if (EQUAL(header_name,"SUBJECT")) {                                     
  18409.            ap->subject = cp;                                                    
  18410.    }                                                                            
  18411.    else if (EQUAL(header_name,"MESSAGE-ID")) {                                  
  18412.            ap->message_id = cp;                                                 
  18413.    }                                                                            
  18414.    else if (EQUAL(header_name,"DATE")) {                                        
  18415.            cp = strpbrk(cp,"0123456789");                                       
  18416.            if (cp == NULL) cp = "*BAD DATE*";                                   
  18417.            ap->date = cp;                                                       
  18418.    }                                                                            
  18419.                                                                                 
  18420.  }                                                                              
  18421.                                                                                 
  18422.  /* Prepare ISPF variables for possible panel or message processing. */         
  18423.                                                                                 
  18424.  if (!np->batch_mode) {                                                         
  18425.    (void)NNMivput(np,"NNTSUBJ " ,ap->subject,-1);                               
  18426.  }                                                                              
  18427.                                                                                 
  18428.  /* Since we retrieved the article, it can't be missing, can it? */             
  18429.                                                                                 
  18430.  vp = &V_STATUS(gp,ap->number);                                                 
  18431.  switch (*vp) {                                                                 
  18432.    case V_MISSING_READ:   *vp = V_READ;   ap->action = NO_ACTION; break;        
  18433.    case V_MISSING_UNREAD: *vp = V_UNREAD; ap->action = NO_ACTION; break;        
  18434.  }                                                                              
  18435.                                                                                 
  18436.  return TRUE;                                                                   
  18437.                                                                                 
  18438. }                                                                               
  18439.                                                                                 
  18440. ./   ADD NAME=NNMRBFM,SSI=01070022                                              
  18441.                                                                                 
  18442.  /********************************************************************/         
  18443.  /*                                                                  */         
  18444.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  18445.  /*                                                                  */         
  18446.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  18447.  /* including the implied warranties of merchantability and fitness, */         
  18448.  /* are expressly denied.                                            */         
  18449.  /*                                                                  */         
  18450.  /* Provided this copyright notice is included, this software may    */         
  18451.  /* be freely distributed and not offered for sale.                  */         
  18452.  /*                                                                  */         
  18453.  /* Changes or modifications may be made and used only by the maker  */         
  18454.  /* of same, and not further distributed.  Such modifications should */         
  18455.  /* be mailed to the author for consideration for addition to the    */         
  18456.  /* software and incorporation in subsequent releases.               */         
  18457.  /*                                                                  */         
  18458.  /********************************************************************/         
  18459.                                                                                 
  18460. #pragma  csect(code,  "NN@RBFM ")                                               
  18461. #pragma  csect(static,"NN$RBFM ")                                               
  18462. #include "nn.h"                                                                 
  18463.                                                                                 
  18464. /****** Report bad format message. ***********************************/         
  18465.                                                                                 
  18466. void                                                                            
  18467. NNMrbfm(np)                                                                     
  18468. Rstruc nncb  *np;                                                               
  18469. {                                                                               
  18470.                                                                                 
  18471.  NNMclrtx(np,NULL);                         /* Clear text */                    
  18472.                                                                                 
  18473.  CRIT2("NNTP message from server %s has invalid format.", np->nnserver);        
  18474.                                                                                 
  18475.  (void)NNMouttx(np,np->server_buf,NULL);    /* Output text line */              
  18476.  NNMvtx(np,NULL,NULL);                      /* View text */                     
  18477.                                                                                 
  18478.  return;                                                                        
  18479. }                                                                               
  18480.                                                                                 
  18481. ./   ADD NAME=NNMRECON,SSI=01090026                                             
  18482.                                                                                 
  18483.  /********************************************************************/         
  18484.  /*                                                                  */         
  18485.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  18486.  /*                                                                  */         
  18487.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  18488.  /* including the implied warranties of merchantability and fitness, */         
  18489.  /* are expressly denied.                                            */         
  18490.  /*                                                                  */         
  18491.  /* Provided this copyright notice is included, this software may    */         
  18492.  /* be freely distributed and not offered for sale.                  */         
  18493.  /*                                                                  */         
  18494.  /* Changes or modifications may be made and used only by the maker  */         
  18495.  /* of same, and not further distributed.  Such modifications should */         
  18496.  /* be mailed to the author for consideration for addition to the    */         
  18497.  /* software and incorporation in subsequent releases.               */         
  18498.  /*                                                                  */         
  18499.  /********************************************************************/         
  18500.                                                                                 
  18501. #pragma  csect(code,  "NN@RECON")                                               
  18502. #pragma  csect(static,"NN$RECON")                                               
  18503. #include "nn.h"                                                                 
  18504.                                                                                 
  18505. /****** Reconnect to server. *****************************************/         
  18506.                                                                                 
  18507. Bool                                                                            
  18508. NNMrecon(np)                                                                    
  18509. Rstruc nncb        *np;                                                         
  18510. {                                                                               
  18511.  struct newsgroup  *gp;                                                         
  18512.  char               save_command[CLIENT_BUF_MSGSIZE+4];                         
  18513.                                                                                 
  18514.  np->connected_to_server   = FALSE;                                             
  18515.  np->reconnect_in_progress = TRUE;                                              
  18516.                                                                                 
  18517.  if (!np->batch_mode) {                                                         
  18518.    (void)NNMispf(np,"CONTROL DISPLAY LOCK");                                    
  18519.    (void)NNMispf(np,"DISPLAY PANEL(NNMLRCON)");                                 
  18520.  }                                                                              
  18521.                                                                                 
  18522.  /*                                                                             
  18523.   * fprintf(stderr,"Lost connection, possible timeout.\n");                     
  18524.   * fprintf(stderr,"Attempting reconnection to news server %s (%s)\n",          
  18525.   *                np->server_hostname,                                         
  18526.   *                np->server_ip_addrstr);                                      
  18527.   */                                                                            
  18528.                                                                                 
  18529.  if (!NNMconn(np)) {                 /* Connect to news server */               
  18530.    CRIT2("Reconnection failed to server %s after disconnect.",                  
  18531.          np->nnserver);                                                         
  18532.    return FALSE;                                                                
  18533.  }                                                                              
  18534.                                                                                 
  18535.  if ((gp=np->current_newsgroup)) {                                              
  18536.                                                                                 
  18537.    if (!np->batch_mode) {                                                       
  18538.      (void)NNMispf(np,"CONTROL DISPLAY LOCK");                                  
  18539.      (void)NNMispf(np,"DISPLAY PANEL(NNMLRSNG)");                               
  18540.    }                                                                            
  18541.                                                                                 
  18542.    strcpy(save_command,np->nntp_command);                                       
  18543.    /* Establish newsgroup */                                                    
  18544.    if (!NNMestng(np,gp->name)) {                                                
  18545.      strcpy(np->nntp_command,save_command);                                     
  18546.      CRIT3(                                                                     
  18547.        "Reselect of newsgroup %s failed during reconnection to %s.",            
  18548.        gp->name, np->nnserver);                                                 
  18549.      return FALSE;                                                              
  18550.    }                                                                            
  18551.    strcpy(np->nntp_command,save_command);                                       
  18552.  }                                                                              
  18553.  np->reconnect_in_progress = FALSE;                                             
  18554.  return TRUE;                                                                   
  18555. }                                                                               
  18556.                                                                                 
  18557. ./   ADD NAME=NNMRPERR,SSI=01060009                                             
  18558.                                                                                 
  18559.  /********************************************************************/         
  18560.  /*                                                                  */         
  18561.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  18562.  /*                                                                  */         
  18563.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  18564.  /* including the implied warranties of merchantability and fitness, */         
  18565.  /* are expressly denied.                                            */         
  18566.  /*                                                                  */         
  18567.  /* Provided this copyright notice is included, this software may    */         
  18568.  /* be freely distributed and not offered for sale.                  */         
  18569.  /*                                                                  */         
  18570.  /* Changes or modifications may be made and used only by the maker  */         
  18571.  /* of same, and not further distributed.  Such modifications should */         
  18572.  /* be mailed to the author for consideration for addition to the    */         
  18573.  /* software and incorporation in subsequent releases.               */         
  18574.  /*                                                                  */         
  18575.  /********************************************************************/         
  18576.                                                                                 
  18577. #pragma  csect(code,  "NN@RPERR")                                               
  18578. #pragma  csect(static,"NN$RPERR")                                               
  18579. #include "nn.h"                                                                 
  18580.                                                                                 
  18581. /****** Report protocol error. ***************************************/         
  18582.                                                                                 
  18583. void                                                                            
  18584. NNMrperr(np)                                                                    
  18585. Rstruc nncb  *np;                                                               
  18586. {                                                                               
  18587.                                                                                 
  18588.  NNMclrtx(np,NULL);                         /* Clear text */                    
  18589.                                                                                 
  18590.  CRIT2("NNTP protocol error.  Unexpected response by server %s.",               
  18591.        np->nnserver);                                                           
  18592.                                                                                 
  18593.  (void)NNMouttx(np,np->server_buf,NULL);    /* Output text line */              
  18594.  NNMvtx(np,NULL,NULL);                      /* View text */                     
  18595.                                                                                 
  18596.  return;                                                                        
  18597. }                                                                               
  18598.                                                                                 
  18599. ./   ADD NAME=NNMSAVE,SSI=01050012                                              
  18600.                                                                                 
  18601.  /********************************************************************/         
  18602.  /*                                                                  */         
  18603.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  18604.  /*                                                                  */         
  18605.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  18606.  /* including the implied warranties of merchantability and fitness, */         
  18607.  /* are expressly denied.                                            */         
  18608.  /*                                                                  */         
  18609.  /* Provided this copyright notice is included, this software may    */         
  18610.  /* be freely distributed and not offered for sale.                  */         
  18611.  /*                                                                  */         
  18612.  /* Changes or modifications may be made and used only by the maker  */         
  18613.  /* of same, and not further distributed.  Such modifications should */         
  18614.  /* be mailed to the author for consideration for addition to the    */         
  18615.  /* software and incorporation in subsequent releases.               */         
  18616.  /*                                                                  */         
  18617.  /********************************************************************/         
  18618.                                                                                 
  18619. #pragma  csect(code,  "NN@SAVE ")                                               
  18620. #pragma  csect(static,"NN$SAVE ")                                               
  18621. #include "nn.h"                                                                 
  18622. #include "nnbatch.h"                                                            
  18623.                                                                                 
  18624. /****** Save NEWSRC file. ********************************************/         
  18625.                                                                                 
  18626. Bool                                                                            
  18627. NNMsave(np,rest)                                                                
  18628. Rstruc nncb         *np;                                                        
  18629. char                *rest;                                                      
  18630. {                                                                               
  18631.  Rstruc batch       *bp;                                                        
  18632.                                                                                 
  18633.  if (np->batch_mode) {                                                          
  18634.    bp = np->batch_hook;                                                         
  18635.    if (GETB("CHECKPOINT") == FALSE) return TRUE;                                
  18636.  }                                                                              
  18637.                                                                                 
  18638.  NNMcnrf(np,NULL,TRUE);  /* Close NEWSRC file */                                
  18639.                                                                                 
  18640.  /* Reopen the file for input.  Don't let anybody else sneak in. */             
  18641.                                                                                 
  18642.  if (!(np->newsrc_file = fopen(np->newsrc_to_open,"r"))) {                      
  18643.    perror("Cannot reopen NEWSRC file");                                         
  18644.  }                                                                              
  18645.                                                                                 
  18646.  return TRUE;                                                                   
  18647. }                                                                               
  18648.                                                                                 
  18649. ./   ADD NAME=NNMSOCKT,SSI=01080032                                             
  18650.                                                                                 
  18651.  /********************************************************************/         
  18652.  /*                                                                  */         
  18653.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  18654.  /*                                                                  */         
  18655.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  18656.  /* including the implied warranties of merchantability and fitness, */         
  18657.  /* are expressly denied.                                            */         
  18658.  /*                                                                  */         
  18659.  /* Provided this copyright notice is included, this software may    */         
  18660.  /* be freely distributed and not offered for sale.                  */         
  18661.  /*                                                                  */         
  18662.  /* Changes or modifications may be made and used only by the maker  */         
  18663.  /* of same, and not further distributed.  Such modifications should */         
  18664.  /* be mailed to the author for consideration for addition to the    */         
  18665.  /* software and incorporation in subsequent releases.               */         
  18666.  /*                                                                  */         
  18667.  /********************************************************************/         
  18668.                                                                                 
  18669. #pragma  csect(code,  "NN@SOCKT")                                               
  18670. #pragma  csect(static,"NN$SOCKT")                                               
  18671. #include "nn.h"                                                                 
  18672.                                                                                 
  18673. /****** Output one data line for the server. *************************/         
  18674.                                                                                 
  18675. Bool                                                                            
  18676. NNMsockt(np)                                                                    
  18677. Rstruc nncb    *np;                                                             
  18678. {                                                                               
  18679.  int            nntp_bytes;                                                     
  18680.  int            writrc;                                                         
  18681.  int            j;                                                              
  18682.  char          *s_buf;                                                          
  18683.                                                                                 
  18684.  nntp_bytes = strlen(np->nntp_command);                                         
  18685.                                                                                 
  18686.  memcpy(np->client_buf,np->nntp_command,nntp_bytes);                            
  18687.  np->client_buf[nntp_bytes  ] = CARRIAGE_RETURN;                                
  18688.  np->client_buf[nntp_bytes+1] = LINE_FEED;                                      
  18689.                                                                                 
  18690.  /* Before sending a request to the server, do a cleanup operation              
  18691.     to make sure that no more responses are coming from the server.             
  18692.  */                                                                             
  18693.                                                                                 
  18694.  NNMesrvr(np);           /* End server read */                                  
  18695.                                                                                 
  18696.  if (np->receiving_text &&                                                      
  18697.      nntp_bytes == 1    &&                                                      
  18698.      np->client_buf[0] == '.') {                                                
  18699.    np->receiving_text = FALSE;                                                  
  18700.  }                                                                              
  18701.                                                                                 
  18702.  if (np->debug_mode)                                                            
  18703.     NNMdump(np,"Writing to server",np->client_buf,nntp_bytes+2);                
  18704.                                                                                 
  18705. #ifdef MVS                                                                      
  18706.                                                                                 
  18707.  for (j=0;j<nntp_bytes+2;++j) {                                                 
  18708.    np->client_buf[j] = etoa(np->client_buf[j]);                                 
  18709.  }                                                                              
  18710.                                                                                 
  18711. #endif                                                                          
  18712.                                                                                 
  18713.  writrc = write(np->socknum, np->client_buf, nntp_bytes+2);                     
  18714.  if (writrc < 0) {                                                              
  18715.    np->connection_broken = TRUE;                                                
  18716.    if (!np->reconnect_in_progress) {                                            
  18717.      GETMAIN(s_buf,char,CLIENT_BUF_MSGSIZE+4,"socket buffer");                  
  18718.      if (s_buf) {                                                               
  18719.        memcpy(s_buf,np->client_buf,nntp_bytes+2);                               
  18720.        if (NNMrecon(np)) {     /* Reconnect to server */                        
  18721.          writrc = write(np->socknum, s_buf, nntp_bytes+2);                      
  18722.        }                                                                        
  18723.        FREEMAIN(s_buf, "old socket buffer");                                    
  18724.      }                                                                          
  18725.    }                                                                            
  18726.  }                                                                              
  18727.  if (writrc < 0) {                                                              
  18728.    CRIT2("TCP/IP error: write() failed to send data to server %s.",             
  18729.          np->nnserver);                                                         
  18730.    return FALSE;                                                                
  18731.  }                                                                              
  18732.                                                                                 
  18733.  NNMssrvr(np);      /* Start server read */                                     
  18734.                                                                                 
  18735.  return TRUE;                                                                   
  18736. }                                                                               
  18737.                                                                                 
  18738. ./   ADD NAME=NNMSOPT,SSI=01130055                                              
  18739.                                                                                 
  18740.  /********************************************************************/         
  18741.  /*                                                                  */         
  18742.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  18743.  /*                                                                  */         
  18744.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  18745.  /*                                                                  */         
  18746.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  18747.  /* including the implied warranties of merchantability and fitness, */         
  18748.  /* are expressly denied.                                            */         
  18749.  /*                                                                  */         
  18750.  /* Provided this copyright notice is included, this software may    */         
  18751.  /* be freely distributed and not offered for sale.                  */         
  18752.  /*                                                                  */         
  18753.  /* Changes or modifications may be made and used only by the maker  */         
  18754.  /* of same, and not further distributed.  Such modifications should */         
  18755.  /* be mailed to the author for consideration for addition to the    */         
  18756.  /* software and incorporation in subsequent releases.               */         
  18757.  /*                                                                  */         
  18758.  /********************************************************************/         
  18759.                                                                                 
  18760. #pragma  csect(code,  "NN@SOPT ")                                               
  18761. #pragma  csect(static,"NN$SOPT ")                                               
  18762. #include "nn.h"                                                                 
  18763.                                                                                 
  18764. #define BOOLOPTSET(A,B,C) \                                                     
  18765.    switch (A[0]) { \                                                            
  18766.      case  'n': \                                                               
  18767.      case  'N':   B = FALSE; break; \                                           
  18768.      case  'y': \                                                               
  18769.      case  'Y':   B = TRUE; break; \                                            
  18770.      case '\0': \                                                               
  18771.      default:     B = C; break; \                                               
  18772.    }                                                                            
  18773.                                                                                 
  18774. /****** Set options that are stored in ISPF profile. *****************/         
  18775.                                                                                 
  18776. void                                                                            
  18777. NNMsopt(np,which)                                                               
  18778. Rstruc nncb        *np;                                                         
  18779. enum user_option    which;                                                      
  18780. {                                                                               
  18781.  int                arrows;                                                     
  18782.  char               tempinc [256];                                              
  18783.  char               tempexc [256];                                              
  18784.  char               nnmupdtf[ 12];                                              
  18785.  char               nnextpow[  4];                                              
  18786.  char               nnextpap[  4];                                              
  18787.  char               nnupan  [  4];                                              
  18788.  char               nnuprn  [  4];                                              
  18789.  char               nnupra  [  4];                                              
  18790.  char               nnngscr [  4];                                              
  18791.  char               nnarscr [  4];                                              
  18792.  char               nnarrows[  2];                                              
  18793.                                                                                 
  18794.  if (which == OPTION_ALL) {                                                     
  18795.    NNMispf(np,                                                                  
  18796.            "VGET \                                                              
  18797. (NNRFCOPT NNRFCINC NNRFCEXC\                                                    
  18798.  NNUPAN NNUPRN NNUPRA NNMUPDTF NNEXTPOW NNEXTPAP\                               
  18799.  NNNGSCR NNARSCR NNARROWS)\                                                     
  18800.  PROFILE");                                                                     
  18801.  }                                                                              
  18802.                                                                                 
  18803.  if (which == OPTION_ALL || which == OPTION_HEADER) {                           
  18804.                                                                                 
  18805.    (void)NNMivget(np,"NNRFCOPT ", np->nnrfcopt, sizeof(np->nnrfcopt));          
  18806.    (void)NNMivget(np,"NNRFCINC ", tempinc, sizeof(tempinc));                    
  18807.    (void)NNMivget(np,"NNRFCEXC ", tempexc, sizeof(tempexc));                    
  18808.                                                                                 
  18809.    if (!*np->nnrfcopt) strcpy(np->nnrfcopt,"A");                                
  18810.    sprintf(np->nnrfcinc," %s ",tempinc);                                        
  18811.    sprintf(np->nnrfcexc," %s ",tempexc);                                        
  18812.                                                                                 
  18813.  }                                                                              
  18814.                                                                                 
  18815.  if (which == OPTION_ALL || which == OPTION_OTHER) {                            
  18816.                                                                                 
  18817.    (void)NNMivget(np,"NNUPAN ",   nnupan,   sizeof(nnupan  ));                  
  18818.    (void)NNMivget(np,"NNUPRN ",   nnuprn,   sizeof(nnuprn  ));                  
  18819.    (void)NNMivget(np,"NNUPRA ",   nnupra,   sizeof(nnupra  ));                  
  18820.    (void)NNMivget(np,"NNMUPDTF ", nnmupdtf, sizeof(nnmupdtf));                  
  18821.    (void)NNMivget(np,"NNEXTPOW ", nnextpow, sizeof(nnextpow));                  
  18822.    (void)NNMivget(np,"NNEXTPAP ", nnextpap, sizeof(nnextpap));                  
  18823.                                                                                 
  18824.    /* 5 is a "reasonable" default, according to DDI */                          
  18825.                                                                                 
  18826.    if      (nnmupdtf[0] == '\0')     np->updatefreq = 5;                        
  18827.    else if (EQUAL(nnmupdtf, "OFF"))  np->updatefreq = -1;                       
  18828.    else if (EQUAL(nnmupdtf, "ON"))   np->updatefreq = 0;                        
  18829.    else                              np->updatefreq = atoi(nnmupdtf);           
  18830.                                                                                 
  18831.    BOOLOPTSET(nnupan,   np->update_adding_newsgroups,    FALSE);                
  18832.    BOOLOPTSET(nnuprn,   np->update_rewriting_newsrc,     TRUE);                 
  18833.    BOOLOPTSET(nnupra,   np->update_retrieving_articles,  TRUE);                 
  18834.    BOOLOPTSET(nnextpow, np->warn_overwrite,              TRUE);                 
  18835.    BOOLOPTSET(nnextpap, np->warn_append,                 TRUE);                 
  18836.                                                                                 
  18837.    if (np->update_retrieving_articles == FALSE) {                               
  18838.      np->updatefreq = -1;                                                       
  18839.    }                                                                            
  18840.  }                                                                              
  18841.                                                                                 
  18842.  if (which == OPTION_ALL || which == OPTION_VIEW) {                             
  18843.                                                                                 
  18844.    (void)NNMivget(np,"NNNGSCR ",  nnngscr,  sizeof(nnngscr ));                  
  18845.    (void)NNMivget(np,"NNARSCR ",  nnarscr,  sizeof(nnarscr ));                  
  18846.    (void)NNMivget(np,"NNARROWS ", nnarrows, sizeof(nnarrows));                  
  18847.                                                                                 
  18848.    BOOLOPTSET(nnngscr,  np->newsgroup_autoscroll,        TRUE);                 
  18849.    BOOLOPTSET(nnarscr,  np->article_autoscroll,          TRUE);                 
  18850.                                                                                 
  18851.    switch (nnarrows[0]) {                                                       
  18852.      case  '1':                                                                 
  18853.      default:     arrows = 1;              break;                               
  18854.      case  '2':   arrows = 2;              break;                               
  18855.      case  '3':   arrows = 3;              break;                               
  18856.    }                                                                            
  18857.                                                                                 
  18858.    if (arrows != np->article_rows) {                                            
  18859.      np->article_rows = arrows;                                                 
  18860.      np->article_criterion_changed = TRUE;                                      
  18861.    }                                                                            
  18862.  }                                                                              
  18863.                                                                                 
  18864.  return;                                                                        
  18865. }                                                                               
  18866.                                                                                 
  18867. ./   ADD NAME=NNMSORT,SSI=01060043                                              
  18868.                                                                                 
  18869.  /********************************************************************/         
  18870.  /*                                                                  */         
  18871.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  18872.  /*                                                                  */         
  18873.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  18874.  /*                                                                  */         
  18875.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  18876.  /* including the implied warranties of merchantability and fitness, */         
  18877.  /* are expressly denied.                                            */         
  18878.  /*                                                                  */         
  18879.  /* Provided this copyright notice is included, this software may    */         
  18880.  /* be freely distributed and not offered for sale.                  */         
  18881.  /*                                                                  */         
  18882.  /* Changes or modifications may be made and used only by the maker  */         
  18883.  /* of same, and not further distributed.  Such modifications should */         
  18884.  /* be mailed to the author for consideration for addition to the    */         
  18885.  /* software and incorporation in subsequent releases.               */         
  18886.  /*                                                                  */         
  18887.  /********************************************************************/         
  18888.                                                                                 
  18889. #pragma  csect(code,  "NN@SORT ")                                               
  18890. #pragma  csect(static,"NN$SORT ")                                               
  18891. #include "nn.h"                                                                 
  18892.                                                                                 
  18893. /****** Compare articles by number. **********************************/         
  18894.                                                                                 
  18895. static int                                                                      
  18896. compare_articles_by_number(ap1,ap2)                                             
  18897. register const void       *ap1;                                                 
  18898. register const void       *ap2;                                                 
  18899. {                                                                               
  18900.  return                                                                         
  18901.          ((struct newsarticle *)ap1)->number                                    
  18902.        - ((struct newsarticle *)ap2)->number                                    
  18903.          ;                                                                      
  18904. }                                                                               
  18905.                                                                                 
  18906. /****** Compare articles by subject. *********************************/         
  18907.                                                                                 
  18908. static int                                                                      
  18909. compare_articles_by_subject(ap1,ap2)                                            
  18910. register const void       *ap1;                                                 
  18911. register const void       *ap2;                                                 
  18912. {                                                                               
  18913.  int answer;                                                                    
  18914.                                                                                 
  18915.  answer = strcmp(                                                               
  18916.                  ((struct newsarticle *)ap1)->csubject,                         
  18917.                  ((struct newsarticle *)ap2)->csubject                          
  18918.                 );                                                              
  18919.  if (answer == 0) return compare_articles_by_number(ap1,ap2);                   
  18920.  else return answer;                                                            
  18921.                                                                                 
  18922. }                                                                               
  18923.                                                                                 
  18924. /****** Make canonical subject. *************************************/          
  18925.                                                                                 
  18926. static char *                                                                   
  18927. make_canonical_subject(spp,subject)                                             
  18928. char                 **spp;                                                     
  18929. char                  *subject;                                                 
  18930. {                                                                               
  18931.  char                 *ip;                                                      
  18932.  char                 *op;                                                      
  18933.  char                 *rp;                                                      
  18934.  int                   re_count;                                                
  18935.                                                                                 
  18936.  if (!*subject) return "";                                                      
  18937.                                                                                 
  18938.  /* Scan past "re"s and count them up */                                        
  18939.                                                                                 
  18940.  rp = *spp;                                                                     
  18941.                                                                                 
  18942.  re_count = -1;                                                                 
  18943.  ip = subject - 3;                                                              
  18944.  do {                                                                           
  18945.    ip = ip + 3 + strspn(ip + 3," \t");                                          
  18946.    re_count++;                                                                  
  18947.  } while (!memcmp(ip,"Re:",3) ||                                                
  18948.           !memcmp(ip,"re:",3) ||                                                
  18949.        /* !memcmp(ip,"rE:",3) || - do you really expect this??? */              
  18950.           !memcmp(ip,"RE:",3));                                                 
  18951.                                                                                 
  18952.  /* Copy subject to buffer while lowercasing. */                                
  18953.                                                                                 
  18954.  for (/* ip set above, */ op = rp; *ip; ip++, op++) *op = tolower(*ip);         
  18955.                                                                                 
  18956.  /* Squash trailing spaces */                                                   
  18957.                                                                                 
  18958.  for (; op > rp && isspace(*(op-1)); op--);                                     
  18959.                                                                                 
  18960.  /* Hack for prioritizing RE:'s.  Add a byte at the end to put                  
  18961.   * subjects in order.  e.g.:                                                   
  18962.   * Subject: Foo              --> "foo\0"                                       
  18963.   * Subject: Re: Foo          --> "foo\001\0"                                   
  18964.   * Subject: Re: Re: Foo      --> "foo\002\0"                                   
  18965.   *                                                                             
  18966.   * This algorithm will break if there are more than 255 "RE:"s,                
  18967.   * but do you really think that's likely?                                      
  18968.   */                                                                            
  18969.                                                                                 
  18970.  if (re_count > 0) {                                                            
  18971.    *op = (unsigned char) re_count;                                              
  18972.    op++;                                                                        
  18973.  }                                                                              
  18974.  *op = '\0';                                                                    
  18975.                                                                                 
  18976.  *spp = op + 1;   /* Bump buffer pointer past our new end */                    
  18977.                                                                                 
  18978.  return rp;                                                                     
  18979.                                                                                 
  18980. }                                                                               
  18981.                                                                                 
  18982. /****** Sort article table. *****************************************/          
  18983.                                                                                 
  18984. void                                                                            
  18985. NNMsort(np,gp)                                                                  
  18986. Rstruc nncb         *np;                                                        
  18987. Rstruc newsgroup    *gp;                                                        
  18988. {                                                                               
  18989.  Rstruc newsarticle *ap;                                                        
  18990.  char               *sortbuf;                                                   
  18991.  char               *sp;                                                        
  18992.  int                 sortbufsize;                                               
  18993.                                                                                 
  18994.  if (!gp->first_article) return;                                                
  18995.                                                                                 
  18996.  if (np->sort_by_subject) {                                                     
  18997.                                                                                 
  18998.    /* Get enough memory to hold all essential article subjects. */              
  18999.                                                                                 
  19000.    sortbufsize = 0;                                                             
  19001.    for (ap = gp->first_article; ap <= gp->fake_last_article; ap++) {            
  19002.      if (*ap->subject) sortbufsize += strlen(ap->subject) + 1;                  
  19003.    }                                                                            
  19004.                                                                                 
  19005.    GETMAIN(sortbuf, char, sortbufsize, "sort-by-subject buffer");               
  19006.    if (!sortbuf) {                                                              
  19007.      CRIT1("Not enough memory to sort articles by subject");                    
  19008.      return;                                                                    
  19009.    }                                                                            
  19010.                                                                                 
  19011.    sp = sortbuf;                                                                
  19012.    for (ap = gp->first_article; ap <= gp->fake_last_article; ap++) {            
  19013.      ap->csubject = make_canonical_subject(&sp,ap->subject);                    
  19014.    }                                                                            
  19015.                                                                                 
  19016.    qsort(gp->first_article, gp->fake_article_count,                             
  19017.          sizeof(struct newsarticle),                                            
  19018.          compare_articles_by_subject);                                          
  19019.                                                                                 
  19020.    /* This isn't strictly necessary as long as no one tries to refer            
  19021.     * to ap->csubject outside of this module.                                   
  19022.     *                                                                           
  19023.    for (ap = gp->first_article; ap <= gp->fake_last_article; ap++) {            
  19024.      ap->csubject = NULL;                                                       
  19025.    }                                                                            
  19026.     *                                                                           
  19027.     */                                                                          
  19028.                                                                                 
  19029.    FREEMAIN(sortbuf,"sort-by-subject buffer");                                  
  19030.                                                                                 
  19031.  }                                                                              
  19032.  else {                                                                         
  19033.    qsort(gp->first_article, gp->fake_article_count,                             
  19034.          sizeof(struct newsarticle),                                            
  19035.          compare_articles_by_number);                                           
  19036.  }                                                                              
  19037.                                                                                 
  19038.  return;                                                                        
  19039. }                                                                               
  19040.                                                                                 
  19041. ./   ADD NAME=NNMSSRVR,SSI=01020042                                             
  19042.                                                                                 
  19043.  /********************************************************************/         
  19044.  /*                                                                  */         
  19045.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  19046.  /*                                                                  */         
  19047.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  19048.  /* including the implied warranties of merchantability and fitness, */         
  19049.  /* are expressly denied.                                            */         
  19050.  /*                                                                  */         
  19051.  /* Provided this copyright notice is included, this software may    */         
  19052.  /* be freely distributed and not offered for sale.                  */         
  19053.  /*                                                                  */         
  19054.  /* Changes or modifications may be made and used only by the maker  */         
  19055.  /* of same, and not further distributed.  Such modifications should */         
  19056.  /* be mailed to the author for consideration for addition to the    */         
  19057.  /* software and incorporation in subsequent releases.               */         
  19058.  /*                                                                  */         
  19059.  /********************************************************************/         
  19060.                                                                                 
  19061. #pragma  csect(code,  "NN@SSRVR")                                               
  19062. #pragma  csect(static,"NN$SSRVR")                                               
  19063. #include "nn.h"                                                                 
  19064.                                                                                 
  19065. /****** Start server read. *******************************************/         
  19066.                                                                                 
  19067. void                                                                            
  19068. NNMssrvr(np)                                                                    
  19069. Rstruc nncb  *np;                                                               
  19070. {                                                                               
  19071.                                                                                 
  19072.  np->server_has_something_pending = TRUE;                                       
  19073.  np->server_finished_replying     = FALSE;                                      
  19074.  np->sending_text                 = FALSE;                                      
  19075.  np->something_to_print           = FALSE;                                      
  19076.  np->dont_read                    = FALSE;                                      
  19077.                                                                                 
  19078.  return;                                                                        
  19079.                                                                                 
  19080. }                                                                               
  19081.                                                                                 
  19082. ./   ADD NAME=NNMSTRLC,SSI=01010025                                             
  19083.                                                                                 
  19084.  /********************************************************************/         
  19085.  /*                                                                  */         
  19086.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  19087.  /*                                                                  */         
  19088.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  19089.  /* including the implied warranties of merchantability and fitness, */         
  19090.  /* are expressly denied.                                            */         
  19091.  /*                                                                  */         
  19092.  /* Provided this copyright notice is included, this software may    */         
  19093.  /* be freely distributed and not offered for sale.                  */         
  19094.  /*                                                                  */         
  19095.  /* Changes or modifications may be made and used only by the maker  */         
  19096.  /* of same, and not further distributed.  Such modifications should */         
  19097.  /* be mailed to the author for consideration for addition to the    */         
  19098.  /* software and incorporation in subsequent releases.               */         
  19099.  /*                                                                  */         
  19100.  /********************************************************************/         
  19101.                                                                                 
  19102. #pragma  csect(code,  "NN@STRLC")                                               
  19103. #pragma  csect(static,"NN$STRLC")                                               
  19104. #include "nn.h"                                                                 
  19105.                                                                                 
  19106. /****** Case-insensitive string search. ******************************/         
  19107.                                                                                 
  19108.   /* This differs from the Ustrstr function in NNMbbexp in that it only         
  19109.    * has to lowercase the "b" argument, not both.  The "a" argument             
  19110.    * is assumed to be all lower case already.                                   
  19111.    */                                                                           
  19112.                                                                                 
  19113. char *                                                                          
  19114. NNMstrlc(b,a)                                                                   
  19115. register char  *b;                                                              
  19116. register char  *a;                                                              
  19117. {                                                                               
  19118.  register char *aa;                                                             
  19119.  register char *bb;                                                             
  19120.                                                                                 
  19121.  if (!*a) return strchr(b,'\0');                                                
  19122.                                                                                 
  19123.  for (;;) {                                                                     
  19124.                                                                                 
  19125.    while (*b && (*a != tolower(*b))) b++;                                       
  19126.                                                                                 
  19127.    if (!*b) return NULL;                                                        
  19128.                                                                                 
  19129.    for (aa = a, bb = b;                                                         
  19130.         *aa && *bb && (*aa == tolower(*bb));                                    
  19131.         aa++, bb++) ;                                                           
  19132.                                                                                 
  19133.    if (!*aa) return a;                                                          
  19134.                                                                                 
  19135.    b++;                                                                         
  19136.  }                                                                              
  19137.                                                                                 
  19138. }                                                                               
  19139.                                                                                 
  19140. ./   ADD NAME=NNMSUMAT,SSI=01060020                                             
  19141.                                                                                 
  19142.  /********************************************************************/         
  19143.  /*                                                                  */         
  19144.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  19145.  /*                                                                  */         
  19146.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  19147.  /* including the implied warranties of merchantability and fitness, */         
  19148.  /* are expressly denied.                                            */         
  19149.  /*                                                                  */         
  19150.  /* Provided this copyright notice is included, this software may    */         
  19151.  /* be freely distributed and not offered for sale.                  */         
  19152.  /*                                                                  */         
  19153.  /* Changes or modifications may be made and used only by the maker  */         
  19154.  /* of same, and not further distributed.  Such modifications should */         
  19155.  /* be mailed to the author for consideration for addition to the    */         
  19156.  /* software and incorporation in subsequent releases.               */         
  19157.  /*                                                                  */         
  19158.  /********************************************************************/         
  19159.                                                                                 
  19160. #pragma  csect(code,  "NN@SUMAT")                                               
  19161. #pragma  csect(static,"NN$SUMAT")                                               
  19162. #include "nn.h"                                                                 
  19163.                                                                                 
  19164. /****** Subject matching code. ***************************************/         
  19165.                                                                                 
  19166. Bool                                                                            
  19167. NNMsumat(a,b)                                                                   
  19168. char        *a;                                                                 
  19169. char        *b;                                                                 
  19170. {                                                                               
  19171.  char       *cp;                                                                
  19172.  char       *c1;                                                                
  19173.  char       *c2;                                                                
  19174.  char        bracket;                                                           
  19175.  char        s1[257];                                                           
  19176.  char        s2[257];                                                           
  19177.                                                                                 
  19178.  strncpy(s1,a,256);                                                             
  19179.  strncpy(s2,b,256);                                                             
  19180.                                                                                 
  19181.  for (cp=s1; *cp; cp++) *cp = tolower(*cp);                                     
  19182.  for (; cp > s1 && isspace(*(cp-1)); cp--);                                     
  19183.  *cp = '\0';                                                                    
  19184.                                                                                 
  19185.  for (cp=s2; *cp; cp++) *cp = tolower(*cp);                                     
  19186.  for (; cp > s2 && isspace(*(cp-1)); cp--);                                     
  19187.  *cp = '\0';                                                                    
  19188.                                                                                 
  19189.  c1 = s1 + strspn(s1," \t");                                                    
  19190.  c2 = s2 + strspn(s2," \t");                                                    
  19191.                                                                                 
  19192.  if (!strcmp(c1,c2)) return TRUE;                                               
  19193.                                                                                 
  19194.  while (!memcmp(c1,"re:",3)) {                                                  
  19195.    c1 = c1+3 + strspn(c1+3," \t");                                              
  19196.    if (!strcmp(c1,c2)) return TRUE;                                             
  19197.  }                                                                              
  19198.  while (!memcmp(c2,"re:",3)) {                                                  
  19199.    c2 = c2+3 + strspn(c2+3," \t");                                              
  19200.    if (!strcmp(c1,c2)) return TRUE;                                             
  19201.  }                                                                              
  19202.                                                                                 
  19203.  if ((cp=strstr(c1,"(was:" /*)*/ )) ||                                          
  19204.      (cp=strstr(c1,"(was " /*)*/ )) ||                                          
  19205.      (cp=strstr(c1,"[was " /*)*/ )) ||                                          
  19206.      (cp=strstr(c1,"[was:" /*)*/ ))) {                                          
  19207.    switch (*cp) {                                                               
  19208.      case '(':  bracket = ')';  break;                                          
  19209.      case '[':  bracket = ']';  break;                                          
  19210.      default:   bracket = '\0'; break;                                          
  19211.    }                                                                            
  19212.    c1 = cp+5 + strspn(cp+5," \t");                                              
  19213.    if (!memcmp(c1,"re:",3)) c1 = c1+3 + strspn(c1+3," \t");                     
  19214.    if (!strcmp(c1,c2)) return TRUE;                                             
  19215.    cp = c1 + strlen(c1) - 1;                                                    
  19216.    if (*cp == bracket) *cp = '\0';                                              
  19217.    if (!strcmp(c1,c2)) return TRUE;                                             
  19218.  }                                                                              
  19219.  if ((cp=strstr(c2,"(was:" /*)*/ )) ||                                          
  19220.      (cp=strstr(c2,"(was " /*)*/ )) ||                                          
  19221.      (cp=strstr(c2,"[was " /*)*/ )) ||                                          
  19222.      (cp=strstr(c2,"[was:" /*)*/ ))) {                                          
  19223.    switch (*cp) {                                                               
  19224.      case '(':  bracket = ')';  break;                                          
  19225.      case '[':  bracket = ']';  break;                                          
  19226.      default:   bracket = '\0'; break;                                          
  19227.    }                                                                            
  19228.    c2 = cp+5 + strspn(cp+5," \t");                                              
  19229.    if (!memcmp(c2,"re:",3)) c2 = c2+3 + strspn(c2+3," \t");                     
  19230.    if (!strcmp(c1,c2)) return TRUE;                                             
  19231.    cp = c2 + strlen(c2) - 1;                                                    
  19232.    if (*cp == bracket) *cp = '\0';                                              
  19233.    if (!strcmp(c1,c2)) return TRUE;                                             
  19234.  }                                                                              
  19235.                                                                                 
  19236.  if (!strcmp(c1,c2)) return TRUE;                                               
  19237.                                                                                 
  19238.  return FALSE;                                                                  
  19239.                                                                                 
  19240. }                                                                               
  19241.                                                                                 
  19242. ./   ADD NAME=NNMTSO,SSI=01130059                                               
  19243.                                                                                 
  19244.  /********************************************************************/         
  19245.  /*                                                                  */         
  19246.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  19247.  /*                                                                  */         
  19248.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  19249.  /* including the implied warranties of merchantability and fitness, */         
  19250.  /* are expressly denied.                                            */         
  19251.  /*                                                                  */         
  19252.  /* Provided this copyright notice is included, this software may    */         
  19253.  /* be freely distributed and not offered for sale.                  */         
  19254.  /*                                                                  */         
  19255.  /* Changes or modifications may be made and used only by the maker  */         
  19256.  /* of same, and not further distributed.  Such modifications should */         
  19257.  /* be mailed to the author for consideration for addition to the    */         
  19258.  /* software and incorporation in subsequent releases.               */         
  19259.  /*                                                                  */         
  19260.  /********************************************************************/         
  19261.                                                                                 
  19262.  /********************************************************************/         
  19263.  /*                                                                  */         
  19264.  /* Thanks to Michael Van Norman for this code.                      */         
  19265.  /*                                                                  */         
  19266.  /********************************************************************/         
  19267.                                                                                 
  19268. #pragma  csect(code,  "NN@TSO  ")                                               
  19269. #pragma  csect(static,"NN$TSO  ")                                               
  19270. #include "nn.h"                                                                 
  19271.                                                                                 
  19272. #pragma linkage(ikjeftsr,OS)                                                    
  19273.                                                                                 
  19274. #define _IKJEFTSR_FLAGS_AUTH        0x00000000                                  
  19275. #define _IKJEFTSR_FLAGS_COMMAND     0x00000001                                  
  19276. #define _IKJEFTSR_FLAGS_DUMP        0x00000100                                  
  19277. #define _IKJEFTSR_FLAGS_NODUMP      0x00000000                                  
  19278. #define _IKJEFTSR_FLAGS_PROGRAM     0x00000002                                  
  19279. #define _IKJEFTSR_FLAGS_UNAUTH      0x00010000                                  
  19280.                                                                                 
  19281. /****** Issue TSO command. *******************************************/         
  19282.                                                                                 
  19283. int                                                                             
  19284. NNMtso(command)                                                                 
  19285. char        *command;                                                           
  19286. {                                                                               
  19287.  int         flags         = _IKJEFTSR_FLAGS_COMMAND +                          
  19288.                              _IKJEFTSR_FLAGS_UNAUTH;                            
  19289.  int         commandLength = strlen(command);                                   
  19290.  int         rc            = 0;                                                 
  19291.  int         returnCode    = 0;                                                 
  19292.  int         reasonCode    = 0;                                                 
  19293.  int         abendCode     = 0;                                                 
  19294.                                                                                 
  19295.  static int (*ikjeftsr)() = NULL;                                               
  19296.                                                                                 
  19297.  if (!ikjeftsr) {                                                               
  19298.    /*                                                                           
  19299.    ikjeftsr = (int (*)())fetch("ikjeftsr");                                     
  19300.    if (!ikjeftsr) {                                                             
  19301.     */                                                                          
  19302.      /* #pragma linkage( tsoServiceFacility, OS )                               
  19303.       * int (*tsoServiceFacility)( int *, char *, int *,                        
  19304.       *                            int *, int *, int * );                       
  19305.       */                                                                        
  19306.      int tsoEntryAddress;                                                       
  19307.                                                                                 
  19308.      tsoEntryAddress = 0x00000010;    /* Address of CVT */                      
  19309.      tsoEntryAddress = *(int *)(tsoEntryAddress);                               
  19310.      tsoEntryAddress += 0x9C;/*       /* Offset of TVT in CVT */                
  19311.      tsoEntryAddress = *(int *)(tsoEntryAddress);                               
  19312.      tsoEntryAddress += 0x10;/*       /* TSVTASF-TSVT (from IKJTSVT) */         
  19313.      tsoEntryAddress = *(int *)(tsoEntryAddress);                               
  19314.      ikjeftsr = (int (*)())(tsoEntryAddress);                                   
  19315.    /*                                                                           
  19316.    }                                                                            
  19317.    */                                                                           
  19318.  }                                                                              
  19319.                                                                                 
  19320.  if (!ikjeftsr) {                                                               
  19321.    fprintf(stderr,                                                              
  19322.            "Cannot execute TSO commands, can't fetch IKJEFTSR.\n");             
  19323.    return -2;                                                                   
  19324.  }                                                                              
  19325.                                                                                 
  19326.  rc = (*ikjeftsr)(&flags, command, &commandLength,                              
  19327.                           &returnCode, &reasonCode,                             
  19328.                           (int *)((int)(&abendCode) | 0x80000000));             
  19329.                                                                                 
  19330.  if (rc != 0) {                                                                 
  19331.    if (rc > 4) {                                                                
  19332.      fprintf(stderr,"Command failed:%s\n",command);                             
  19333.      if (rc == 20 && reasonCode == 40)                                          
  19334.           fprintf(stderr,"Command was not found.\n");                           
  19335.      else fprintf(stderr,                                                       
  19336.              "rc=%d,returncode=%d,reasoncode=%d,abendcode=%8.8x\n",             
  19337.              rc, returnCode, reasonCode, abendCode);                            
  19338.    }                                                                            
  19339.    if (abendCode != 0) rc = -1;                                                 
  19340.    else rc = returnCode;                                                        
  19341.  }                                                                              
  19342.                                                                                 
  19343.  return rc;                                                                     
  19344. }                                                                               
  19345.                                                                                 
  19346. ./   ADD NAME=NNMUNALC,SSI=01050001                                             
  19347.                                                                                 
  19348.  /********************************************************************/         
  19349.  /*                                                                  */         
  19350.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  19351.  /*                                                                  */         
  19352.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  19353.  /* including the implied warranties of merchantability and fitness, */         
  19354.  /* are expressly denied.                                            */         
  19355.  /*                                                                  */         
  19356.  /* Provided this copyright notice is included, this software may    */         
  19357.  /* be freely distributed and not offered for sale.                  */         
  19358.  /*                                                                  */         
  19359.  /* Changes or modifications may be made and used only by the maker  */         
  19360.  /* of same, and not further distributed.  Such modifications should */         
  19361.  /* be mailed to the author for consideration for addition to the    */         
  19362.  /* software and incorporation in subsequent releases.               */         
  19363.  /*                                                                  */         
  19364.  /********************************************************************/         
  19365.                                                                                 
  19366. #pragma  csect(code,  "NN@UNALC")                                               
  19367. #pragma  csect(static,"NN$UNALC")                                               
  19368. #include "nn.h"                                                                 
  19369.                                                                                 
  19370. /****** Unallocate a data set. ***************************************/         
  19371.                                                                                 
  19372. Bool                                                                            
  19373. NNMunalc(ddname)                                                                
  19374. char         *ddname;                                                           
  19375. {                                                                               
  19376.  __S99parms   stuff99;   /* The manual has it wrong.  No "struct". */           
  19377.  int          rc;                                                               
  19378.  char        *cp;                                                               
  19379.  TEXTUNIT    *tu [2];                                                           
  19380.  TEXTUNIT     tu_ddn;                                                           
  19381.  TEXTUNIT     tu_una;                                                           
  19382.                                                                                 
  19383.  if (!ddname ||                                                                 
  19384.      !*ddname) return TRUE;   /* if no ddname to free, do nothing */            
  19385.                                                                                 
  19386.  memset((char *)&stuff99,0,sizeof(__S99parms));                                 
  19387.                                                                                 
  19388.  stuff99.__S99RBLN   = 20;                                                      
  19389.  stuff99.__S99VERB   = S99VRBUN;                                                
  19390.  stuff99.__S99FLAG1  = 0;                                                       
  19391.  stuff99.__S99ERROR  = 0;                                                       
  19392.  stuff99.__S99INFO   = 0;                                                       
  19393.  stuff99.__S99TXTPP  = tu;                                                      
  19394.  stuff99.__S99FLAG2  = 0;                                                       
  19395.                                                                                 
  19396.  tu[0] = &tu_ddn;                                                               
  19397.  tu[1] = &tu_una;                                                               
  19398.  *(int *)&tu[1] |= 0x80000000;                                                  
  19399.                                                                                 
  19400.  tu_ddn.key     = DUNDDNAM;                                                     
  19401.  tu_ddn.num     = 1;                                                            
  19402.  tu_ddn.ent.len = strlen(ddname);                                               
  19403.  strcpy(tu_ddn.ent.prm,ddname);                                                 
  19404.                                                                                 
  19405.  tu_una.key     = DUNUNALC;                                                     
  19406.  tu_una.num     = 0;                                                            
  19407.                                                                                 
  19408.  for (cp=tu_ddn.ent.prm; *cp; cp++) *cp = toupper(*cp);                         
  19409.                                                                                 
  19410.  rc = svc99(&stuff99);                                                          
  19411.                                                                                 
  19412.  if (rc == 0) return TRUE;                                                      
  19413.  else if (stuff99.__S99ERROR == 0x0438) /* not freed, is not allocated*/        
  19414.          return TRUE;                                                           
  19415.  else {                                                                         
  19416.    NNMdfail(rc,&stuff99);                                                       
  19417.    return FALSE;                                                                
  19418.  }                                                                              
  19419. }                                                                               
  19420.                                                                                 
  19421. ./   ADD NAME=NNMUPDT,SSI=010C0045                                              
  19422.                                                                                 
  19423.  /********************************************************************/         
  19424.  /*                                                                  */         
  19425.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  19426.  /*                                                                  */         
  19427.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  19428.  /*                                                                  */         
  19429.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  19430.  /* including the implied warranties of merchantability and fitness, */         
  19431.  /* are expressly denied.                                            */         
  19432.  /*                                                                  */         
  19433.  /* Provided this copyright notice is included, this software may    */         
  19434.  /* be freely distributed and not offered for sale.                  */         
  19435.  /*                                                                  */         
  19436.  /* Changes or modifications may be made and used only by the maker  */         
  19437.  /* of same, and not further distributed.  Such modifications should */         
  19438.  /* be mailed to the author for consideration for addition to the    */         
  19439.  /* software and incorporation in subsequent releases.               */         
  19440.  /*                                                                  */         
  19441.  /********************************************************************/         
  19442.                                                                                 
  19443. #pragma  csect(code,  "NN@UPDT ")                                               
  19444. #pragma  csect(static,"NN$UPDT ")                                               
  19445. #include "nn.h"                                                                 
  19446.                                                                                 
  19447. /****** Update the screen as frequently as desired. ******************/         
  19448.                                                                                 
  19449. void                                                                            
  19450. NNMupdt(np,cdp,screen)                                                          
  19451. Rstruc nncb           *np;                                                      
  19452. struct countdown      *cdp;                                                     
  19453. char                  *screen;                                                  
  19454. {                                                                               
  19455.   int                  pct;                                                     
  19456.   int                  barsize;                                                 
  19457.   int                  l;                                                       
  19458.   int                  timediff;                                                
  19459.   int                  h;                                                       
  19460.   int                  m;                                                       
  19461.   int                  s;                                                       
  19462.   time_t               thistime;                                                
  19463.   char                 nnmbar[62];                                              
  19464.   char                 nnmestm[9];                                              
  19465.   char                 zhilite[9];                                              
  19466.   char                 temp[8];                                                 
  19467.   char                 display_string[24];                                      
  19468.                                                                                 
  19469.   if (!cdp || !cdp->do_update || np->batch_mode) return;                        
  19470.                                                                                 
  19471.   time(&thistime);                                                              
  19472.                                                                                 
  19473.   if (cdp->done == 0) {                                                         
  19474.     if (cdp->to_do == 0) return;                                                
  19475.     if (np->barchar == '\0') {                                                  
  19476.       (void)NNMivget(np,"ZHILITE ",zhilite,sizeof(zhilite));                    
  19477.       if (zhilite[0] == 'Y') np->barchar = ' ';                                 
  19478.       else                   np->barchar = '@';                                 
  19479.     }                                                                           
  19480.     timediff = -1;                 /* don't display on initial call */          
  19481.     np->lasttime = thistime;                                                    
  19482.     np->firstime = thistime;                                                    
  19483.     memset(nnmestm,' ',sizeof(nnmestm));                                        
  19484.     (void)NNMivput(np, "NNMESTM ", nnmestm, 0);                                 
  19485.   }                                                                             
  19486.   else {                                                                        
  19487.     timediff = (int)difftime(thistime, np->lasttime);                           
  19488.   }                                                                             
  19489.                                                                                 
  19490.   if (timediff >= np->updatefreq) {                                             
  19491.     memset(nnmbar,' ',sizeof(nnmbar));                                          
  19492.     nnmbar[0] = '^';                                                            
  19493.     if (cdp->to_do < 0) {                                                       
  19494.       pct = 0;                                                                  
  19495.       barsize = 1;                                                              
  19496.     }                                                                           
  19497.     else {                                                                      
  19498.       if (cdp->to_do < cdp->done) cdp->to_do = cdp->done;                       
  19499.       pct = cdp->done * 100 / cdp->to_do;                                       
  19500.       barsize = pct * (sizeof(nnmbar) - 2) / 100 + 1;                           
  19501.     }                                                                           
  19502.     memset(nnmbar+1, np->barchar, barsize-1);                                   
  19503.     nnmbar[barsize++] = '/';                                                    
  19504.                                                                                 
  19505. #if 1                                                                           
  19506.                                                                                 
  19507.     /* This code adds the number of currently processed items to the  */        
  19508.     /* right of the bar until it won't fit anymore, then puts it      */        
  19509.     /* inside the bar.                                                */        
  19510.                                                                                 
  19511.     l = sprintf(temp, "%d", cdp->done);                                         
  19512.     if (barsize + l < sizeof(nnmbar)) {                                         
  19513.       memcpy(&nnmbar[barsize], temp, l);                                        
  19514.     }                                                                           
  19515.     else {                                                                      
  19516.       memcpy(&nnmbar[barsize-l-3], temp, l);                                    
  19517.       if (np->barchar != ' ') {                                                 
  19518.         nnmbar[barsize-l-4] = ' ';                                              
  19519.         nnmbar[barsize-3]   = ' ';                                              
  19520.       }                                                                         
  19521.     }                                                                           
  19522.                                                                                 
  19523. #else                                                                           
  19524.                                                                                 
  19525.     /* This code adds the number of currently processed items to the  */        
  19526.     /* right of the bar until it will fit inside, then puts it there. */        
  19527.                                                                                 
  19528.     l = sprintf(temp, "%d", cdp->done);                                         
  19529.     if (barsize - 4 < l + 2) {                                                  
  19530.       memcpy(&nnmbar[barsize], temp, l);                                        
  19531.     }                                                                           
  19532.     else {                                                                      
  19533.       memcpy(&nnmbar[barsize-l-3], temp, l);                                    
  19534.       if (np->barchar != ' ') {                                                 
  19535.         nnmbar[barsize-l-4] = ' ';                                              
  19536.         nnmbar[barsize-3]   = ' ';                                              
  19537.       }                                                                         
  19538.     }                                                                           
  19539.                                                                                 
  19540. #endif                                                                          
  19541.                                                                                 
  19542.     (void)NNMivput(np, "NNMBAR ",nnmbar,sizeof(nnmbar));                        
  19543.                                                                                 
  19544.     l = sprintf(temp, "%d", cdp->to_do);                                        
  19545.     (void)NNMivput(np, "NNMCOUNT", temp, l);                                    
  19546.                                                                                 
  19547.     s = (cdp->to_do - cdp->done) * difftime(thistime, np->firstime)             
  19548.         / cdp->done;                                                            
  19549.     if (s > 0) {                                                                
  19550.       m = s / 60;  s = s % 60;                                                  
  19551.       h = m / 60;  m = m % 60;                                                  
  19552.       sprintf(nnmestm, "%2.2d:%2.2d:%2.2d", h, m, s);                           
  19553.       (void)NNMivput(np, "NNMESTM ", nnmestm, sizeof(nnmestm) - 1);             
  19554.     }                                                                           
  19555.                                                                                 
  19556.     sprintf(display_string, "DISPLAY PANEL(%s)", screen);                       
  19557.     (void)NNMispf(np, "CONTROL DISPLAY LOCK");                                  
  19558.     (void)NNMispf(np, display_string);                                          
  19559.     np->lasttime = thistime;                                                    
  19560.   }                                                                             
  19561.                                                                                 
  19562.   cdp->done++;                                                                  
  19563.                                                                                 
  19564.   return;                                                                       
  19565.                                                                                 
  19566. }                                                                               
  19567.                                                                                 
  19568. ./   ADD NAME=NNMVAR,SSI=01630049                                               
  19569.                                                                                 
  19570.  /********************************************************************/         
  19571.  /*                                                                  */         
  19572.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  19573.  /*                                                                  */         
  19574.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  19575.  /*                                                                  */         
  19576.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  19577.  /* including the implied warranties of merchantability and fitness, */         
  19578.  /* are expressly denied.                                            */         
  19579.  /*                                                                  */         
  19580.  /* Provided this copyright notice is included, this software may    */         
  19581.  /* be freely distributed and not offered for sale.                  */         
  19582.  /*                                                                  */         
  19583.  /* Changes or modifications may be made and used only by the maker  */         
  19584.  /* of same, and not further distributed.  Such modifications should */         
  19585.  /* be mailed to the author for consideration for addition to the    */         
  19586.  /* software and incorporation in subsequent releases.               */         
  19587.  /*                                                                  */         
  19588.  /********************************************************************/         
  19589.                                                                                 
  19590. #pragma  csect(code,  "NN@VAR  ")                                               
  19591. #pragma  csect(static,"NN$VAR  ")                                               
  19592. #include "nn.h"                                                                 
  19593.                                                                                 
  19594. struct ntdynarray {                                                             
  19595.                    struct newsarticle    *article;                              
  19596.                    char                   numstr [6];                           
  19597.                   };                                                            
  19598.                                                                                 
  19599. /****** View articles. ***********************************************/         
  19600.                                                                                 
  19601. static Bool                                                                     
  19602. view_articles(np,gp,restartp)                                                   
  19603. Rstruc nncb           *np;                                                      
  19604. Rstruc newsgroup      *gp;                                                      
  19605. Bool                  *restartp;                                                
  19606. {                                                                               
  19607.  Rstruc newsarticle   *ap;                                                      
  19608.  Rstruc ntdynarray    *ndp;                                                     
  19609.  Rstruc tabledesc     *tdp;                                                     
  19610.  Rstruc seldesc       *sdp;                                                     
  19611.  Rstruc cmddesc       *cdp;                                                     
  19612.  struct ntdynarray    *ntdynarray_start;                                        
  19613.  struct ntdynarray    *ntdynarray_end;                                          
  19614.  struct newsarticle   *save_top_article;                                        
  19615.  int                   display_total;                                           
  19616.  int                   command_index;                                           
  19617.  int                   prc;                                                     
  19618.  int                   nntlvl;                                                  
  19619.  int                   depth;                                                   
  19620.  int                   articles_per_screen;                                     
  19621.  int                   scroll;                                                  
  19622.  int                   zscrolln;                                                
  19623.  int                   dynsize;                                                 
  19624.  int                   rowincr;                                                 
  19625.  int                   rowbump;                                                 
  19626.  int                   actlen;                                                  
  19627.  short                 name_length;                                             
  19628.  Bool                  is_max;                                                  
  19629.  Bool                  is_scroll_word;                                          
  19630.  Bool                  rebuild_dynamic_array;                                   
  19631.  Bool                  selection_processed_ok;                                  
  19632.  Bool                  command_processed_ok;                                    
  19633.  char                 *cp;                                                      
  19634.  char                 *rowp;                                                    
  19635.  char                 *nntdyna;                                                 
  19636.  char                 *act;                                                     
  19637.  char                  aattr;                                                   
  19638.  char                  sel;                                                     
  19639.  VARK                  arts;                                                    
  19640.  struct countdown      cd;                                                      
  19641.  char                  tcmd        [72];                                        
  19642.  char                  nnthead     [81];                                        
  19643.  char                  command      [COMMANDSIZE];                              
  19644.  char                  zverb        [9];                                        
  19645.  char                  zscrolla     [9];                                        
  19646.  char                  rowmessage  [81];                                        
  19647.                                                                                 
  19648.  if (*restartp) {                                                               
  19649.    *restartp = FALSE;                                                           
  19650.    np->article_criterion_changed = TRUE;                                        
  19651.  }                                                                              
  19652.                                                                                 
  19653.  /* First, retrieve all the article headers.                                    
  19654.   * (Some day we may retrieve only as many as we need.)                         
  19655.   * We have to do this right now because this is the only way to                
  19656.   * determine the true sequence of available articles in the array.             
  19657.   * It would be better to get them as we go along, but we would                 
  19658.   * still have to determine the status of each potential article NUMBER         
  19659.   * to fill up contiguous article structure slots.                              
  19660.   */                                                                            
  19661.                                                                                 
  19662.  if (!NNMraarh(np,gp)) return FALSE; /* Retrieve all article headers */         
  19663.                                                                                 
  19664.  /* Get depth of dynamic area (number of rows to display on screen) */          
  19665.                                                                                 
  19666.  (void)NNMispf(np,                                                              
  19667.        "PQUERY PANEL(NNMDAR) AREANAME(NNTDYNA) DEPTH(NNTDEPTH)");               
  19668.  if (np->ispfrc != 0) return FALSE;                                             
  19669.  depth = NNMiget(np,"NNTDEPTH ");                                               
  19670.                                                                                 
  19671.  /* Allocate a block of "ntdynarray" article pointers, one element              
  19672.   * for each article currently being displayed.  This must be big               
  19673.   * enough to fill up the screen.  It is rebuilt every time the                 
  19674.   * display changes, through scrolling or selection activity.                   
  19675.   */                                                                            
  19676.                                                                                 
  19677.  GETMAIN(ntdynarray_start, struct ntdynarray, depth,                            
  19678.          "newsarticle dynamic array");                                          
  19679.  if (!ntdynarray_start) return FALSE;                                           
  19680.                                                                                 
  19681.  /* Get storage for ISPF dynamic area variable to be constructed. */            
  19682.                                                                                 
  19683.  dynsize = 80*depth;                                                            
  19684.  GETMAIN(nntdyna, char, dynsize, "NNTDYNA buffer");                             
  19685.  if (!nntdyna) return FALSE;                                                    
  19686.                                                                                 
  19687.  tdp = np->article_display_table_address;                                       
  19688.                                                                                 
  19689.  rebuild_dynamic_array         = TRUE;                                          
  19690.  scroll                        = 0;                                             
  19691.  save_top_article              = NULL;                                          
  19692.  strcpy(tcmd,"");                                                               
  19693.  strcpy(np->article_only_string,"");                                            
  19694.                                                                                 
  19695.  /* Until we optimize article retrieval, do this for "A"/"Z" option. */         
  19696.                                                                                 
  19697.  if (np->show_all_articles && np->bypass_header_retrieval) {                    
  19698.    WARN1(                                                                       
  19699. "Use TITLES command to get all the article titles from the server.");           
  19700.  }                                                                              
  19701.                                                                                 
  19702.  /* Loop displaying article titles until END. */                                
  19703.                                                                                 
  19704.  cd.do_update = (np->updatefreq >= 0);                                          
  19705.  cd.done      = 0;                                                              
  19706.  cd.to_do     = -1;                                                             
  19707.                                                                                 
  19708.  do {                                                                           
  19709.                                                                                 
  19710.    if (np->article_criterion_changed) {                                         
  19711.      rowincr = np->article_rows;                                                
  19712.      if (rowincr < 1) rowincr = 1;                                              
  19713.      rowbump = 80 * rowincr;                                                    
  19714.      if ((ap=gp->first_article)) {                                              
  19715.        while (ap <= gp->fake_last_article) {                                    
  19716.          OffArticleInTable(ap); /* guilty until proven innocent */              
  19717.          if (ap->number > 0) {                                                  
  19718.            arts = V_STATUS(gp,ap->number);                                      
  19719.            if (np->show_all_articles                                            
  19720.             || arts == V_UNREAD                                                 
  19721.             || (ArticleRetrieved(ap) && !np->unread_articles_only)) {           
  19722.              if (*np->article_only_string) {                                    
  19723.                if (np->show_all_articles||np->bypass_header_retrieval) {        
  19724.                  (void)NNMrarh(np,gp,ap,FALSE,&cd); /* retrv art hdr */         
  19725.                }                                                                
  19726.                if (NNMstrlc(ap->subject,np->article_only_string)) {             
  19727.                  SetArticleInTable(ap);                                         
  19728.                }                                                                
  19729.              }                                                                  
  19730.              else SetArticleInTable(ap);                                        
  19731.            }                                                                    
  19732.                                                                                 
  19733.            /* If status has been changed (read->unread or vice versa),          
  19734.             * alter it now.  But do not change it if the status is read         
  19735.             * and the displayed status has been set to one of those             
  19736.             * funny values like "Extracted".                                    
  19737.             * This is needed because the newsgroup mark and unmark              
  19738.             * operations do not go through the ap actions.                      
  19739.             */                                                                  
  19740.                                                                                 
  19741.            switch (arts) {                                                      
  19742.              case V_READ:                                                       
  19743.                if (ap->action == UNREAD                                         
  19744.                 || ap->action == MISSING                                        
  19745.                 || ap->action == ERROR                                          
  19746.                 || ap->action == NO_ACTION                                      
  19747.                   ) {                                                           
  19748.                                     ap->action = READ;                          
  19749.                }                                                break;          
  19750.              case V_UNREAD:         ap->action = UNREAD       ; break;          
  19751.              case V_MISSING_READ:   ap->action = MISSING      ; break;          
  19752.              case V_MISSING_UNREAD: ap->action = MISSING      ; break;          
  19753.              default:               ap->action = NO_ACTION    ; break;          
  19754.            }                                                                    
  19755.          }                                                                      
  19756.          ap++;                                                                  
  19757.        }                                                                        
  19758.      }                                                                          
  19759.      np->article_criterion_changed = FALSE;                                     
  19760.      rebuild_dynamic_array = TRUE;                                              
  19761.    }                                                                            
  19762.                                                                                 
  19763.    /* If the top article has been changed, adjust the new top article           
  19764.     * so that it makes sense.  What this means is that if the requested         
  19765.     * top article is not eligible for display, move UP until we find            
  19766.     * one that is, and make that one the new top article.  If we run            
  19767.     * out of articles (reach the beginning) without finding an eligible         
  19768.     * one, use the first eligible one following the requested top one.          
  19769.     */                                                                          
  19770.                                                                                 
  19771.    if (np->top_article != save_top_article) {                                   
  19772.      rebuild_dynamic_array = TRUE;                                              
  19773.      if ((ap=np->top_article) && ap != PHONY_NEWS_ARTICLE) {                    
  19774.        while (ap >= gp->first_article && !ArticleInTable(ap)) ap--;             
  19775.        if (ap < gp->first_article)                                              
  19776.             np->top_article = NULL;                                             
  19777.        else np->top_article = ap;                                               
  19778.      }                                                                          
  19779.    }                                                                            
  19780.                                                                                 
  19781.    if (np->top_article == NULL) {                                               
  19782.      np->top_article = gp->first_article;                                       
  19783.      if (!np->top_article) np->top_article = PHONY_NEWS_ARTICLE;                
  19784.    }                                                                            
  19785.                                                                                 
  19786.    /* If a scroll request, process it.  */                                      
  19787.                                                                                 
  19788.    if (scroll > 0) {                                                            
  19789.      rebuild_dynamic_array = TRUE;                                              
  19790.      if ((ap=np->top_article) != PHONY_NEWS_ARTICLE) {                          
  19791.        while (scroll > 0 && ap <= gp->fake_last_article) {                      
  19792.          scroll--;                                                              
  19793.          do {                                                                   
  19794.            ap++;                                                                
  19795.          } while (ap <= gp->fake_last_article && !ArticleInTable(ap));          
  19796.        }                                                                        
  19797.        if (ap > gp->fake_last_article)                                          
  19798.             np->top_article = PHONY_NEWS_ARTICLE;                               
  19799.        else np->top_article = ap;                                               
  19800.      }                                                                          
  19801.    }                                                                            
  19802.    else if (scroll < 0) {                                                       
  19803.      rebuild_dynamic_array = TRUE;                                              
  19804.      if ((ap=np->top_article) == PHONY_NEWS_ARTICLE) {                          
  19805.        ap = gp->fake_last_article;                                              
  19806.        scroll++;                                                                
  19807.      }                                                                          
  19808.      while (scroll < 0 && ap >= gp->first_article) {                            
  19809.        scroll++;                                                                
  19810.        do {                                                                     
  19811.          ap--;                                                                  
  19812.        } while (ap >= gp->first_article && !ArticleInTable(ap));                
  19813.      }                                                                          
  19814.                                                                                 
  19815.      if (ap < gp->first_article)                                                
  19816.           np->top_article = gp->first_article;                                  
  19817.      else np->top_article = ap;                                                 
  19818.    }                                                                            
  19819.                                                                                 
  19820.    if (!np->top_article) np->top_article = PHONY_NEWS_ARTICLE;                  
  19821.                                                                                 
  19822.    /*                                                                           
  19823.     * If necessary, rebuild the array of newsarticle pointers.                  
  19824.     */                                                                          
  19825.                                                                                 
  19826.    if (rebuild_dynamic_array) {                                                 
  19827.      rebuild_dynamic_array = FALSE;                                             
  19828.      articles_per_screen = (depth-1)/np->article_rows + 1;                      
  19829.      cd.do_update = (np->updatefreq >= 0);                                      
  19830.      cd.done      = 0;                                                          
  19831.      cd.to_do     = articles_per_screen;                                        
  19832.      save_top_article = NULL;       /* force reevaluation of top */             
  19833.      ndp = ntdynarray_start;                                                    
  19834.      ndp->article = PHONY_NEWS_ARTICLE;                                         
  19835.      display_total = articles_per_screen;                                       
  19836.      if ((ap=np->top_article) && ap != PHONY_NEWS_ARTICLE) {                    
  19837.        for (; ap <= gp->fake_last_article && display_total > 0; ap++) {         
  19838.          if (ArticleInTable(ap)) {                                              
  19839.            /* If the article is to be displayed but it hasn't been              
  19840.             * retrieved yet, do so now so we don't have emptiness               
  19841.             * in the display - UNLESS the "z" option was specified.             
  19842.             */                                                                  
  19843.            if (!np->bypass_header_retrieval) {                                  
  19844.              NNMrarh(np,gp,ap,TRUE,&cd);  /* Retrieve article header */         
  19845.              if (np->article_error_found) {                                     
  19846.                *restartp = TRUE;                                                
  19847.                return TRUE;                                                     
  19848.              }                                                                  
  19849.            }                                                                    
  19850.            ndp->article = ap;                                                   
  19851.            sprintf(ndp->numstr, "%5d", ap->number);                             
  19852.            if (ap->action == NO_ACTION) {                                       
  19853.              switch (V_STATUS(gp,ap->number)) {                                 
  19854.                case V_UNREAD:          ap->action = UNREAD  ; break;            
  19855.                case V_READ:            ap->action = READ    ; break;            
  19856.                case V_MISSING_UNREAD:  ap->action = MISSING ; break;            
  19857.                case V_MISSING_READ:    ap->action = MISSING ; break;            
  19858.                default:                                     ; break;            
  19859.              }                                                                  
  19860.            }                                                                    
  19861.            display_total--;                                                     
  19862.            ndp++;                                                               
  19863.          }                                                                      
  19864.        }                                                                        
  19865.      }                                                                          
  19866.      np->top_article  = ntdynarray_start->article;                              
  19867.      ntdynarray_end = ndp;                                                      
  19868.    }                                                                            
  19869.                                                                                 
  19870.    save_top_article = np->top_article;                                          
  19871.                                                                                 
  19872.    /* Fill dynamic area with data for groups satisfying criterion. */           
  19873.                                                                                 
  19874.    memset(nntdyna, ' ', dynsize);                                               
  19875.                                                                                 
  19876. #define ROWCPY(A,B,C) {\                                                        
  19877.      name_length = strlen(B); \                                                 
  19878.      if (name_length > C) name_length = C; \                                    
  19879.      memcpy(&rowp[A], B, name_length); \                                        
  19880.                       }                                                         
  19881.                                                                                 
  19882.    for (ndp = ntdynarray_start, rowp = nntdyna;                                 
  19883.         ndp < ntdynarray_end;                                                   
  19884.         ndp++) {                                                                
  19885.      ap = ndp->article;                                                         
  19886.      rowp[ 0]        = DATAIN_HIGH;     /* selection code attribute */          
  19887.      rowp[ 1]        = ' ';             /* selection code field     */          
  19888.      rowp[ 2]        = DATAOUT_BLUE;    /* article number attribute */          
  19889.      memcpy(&rowp[ 3], ndp->numstr, 5); /* article number           */          
  19890.      rowp[ 8]        = DATAOUT_GREEN;   /* article title attribute  */          
  19891.      ROWCPY(9,ap->subject,60);          /* article title            */          
  19892.                                                                                 
  19893.      switch (ap->action) {                                                      
  19894.        case NO_ACTION: act = "No action"; aattr = DATAOUT_TURQ;   break;        
  19895.        case READ:      act = "Read   "  ; aattr = DATAOUT_BLUE;   break;        
  19896.        case RETRIEVED: act = "Retrieved"; aattr = DATAOUT_BLUE;   break;        
  19897.        case EXTRACTED: act = "Extracted"; aattr = DATAOUT_BLUE;   break;        
  19898.        case PRINTED:   act = "Printed"  ; aattr = DATAOUT_BLUE;   break;        
  19899.        case UNREAD:    act = "Unread "  ; aattr = DATAOUT_YELLOW; break;        
  19900.        case MISSING:   act = "Missing"  ; aattr = DATAOUT_TURQ;   break;        
  19901.        case ERROR:     act = "Error  "  ; aattr = DATAOUT_TURQ;   break;        
  19902.        case CANCELLED: act = "Cancelled"; aattr = DATAOUT_BLUE;   break;        
  19903.        default:        act = "???????"  , aattr = DATAOUT_TURQ;   break;        
  19904.      }                                                                          
  19905.      actlen = strlen(act);                                                      
  19906.      memcpy(&rowp[68-actlen],act,actlen);                                       
  19907.      rowp[68-actlen-1] = aattr;                                                 
  19908.                                                                                 
  19909.      if (rowincr == 1) {                                                        
  19910.        rowp[68] = DATAOUT_GREEN;           /* article date attribute */         
  19911.        ROWCPY(69,ap->date,11);                      /* article date  */         
  19912.      }                                                                          
  19913.      else {                                                                     
  19914.        memset(&rowp[68],' ',12);                                                
  19915.      }                                                                          
  19916.                                                                                 
  19917.      if ((rowp+=80) >= nntdyna + dynsize) break;                                
  19918.      if (rowincr >= 2) {                                                        
  19919.        rowp[0] = DATAOUT_GREEN;          /* article author attribute */         
  19920.        ROWCPY(9,ap->from,58);                    /* article author   */         
  19921.        rowp[59] = DATAOUT_GREEN;           /* article date attribute */         
  19922.        ROWCPY(60,ap->date,20);                      /* article date  */         
  19923.        if ((rowp+=80) >= nntdyna + dynsize) break;                              
  19924.        if (rowincr >= 3) {                                                      
  19925.          rowp[0] = DATAOUT_BLUE;                                                
  19926.          ROWCPY(9,ap->message_id,70);                                           
  19927.          if ((rowp+=80) >= nntdyna + dynsize) break;                            
  19928.        }                                                                        
  19929.      }                                                                          
  19930.    }                                                                            
  19931.                                                                                 
  19932.    if (rowp < nntdyna + dynsize) {                                              
  19933.      rowp[0] = DATAOUT_HIGH;                                                    
  19934.      memset(&rowp[1], '-',79);                                                  
  19935.    }                                                                            
  19936.                                                                                 
  19937.  /* Format the heading line for the title display.                              
  19938.   * Row message is "Range mmmm-nnnn", not "m-n of p", because                   
  19939.   * we don't always know if we can get to all the articles.                     
  19940.   */                                                                            
  19941.                                                                                 
  19942.    if (gp->real_first_article_number == NO_VALUE                                
  19943.      && gp->real_last_article_number == NO_VALUE) {                             
  19944.      strcpy(rowmessage, "");                                                    
  19945.    }                                                                            
  19946.    else {                                                                       
  19947.      sprintf(rowmessage, " Range %d-%d",                                        
  19948.                          gp->real_first_article_number,                         
  19949.                          gp->real_last_article_number);                         
  19950.    }                                                                            
  19951.                                                                                 
  19952.    memset(nnthead, '-', 80);                                                    
  19953.    *(nnthead+80) = '\0';                                                        
  19954.    strcpy(nnthead, "Newsgroup: ");                                              
  19955.    name_length = strlen(gp->name);                                              
  19956.    if (name_length > 40) name_length = 40;                                      
  19957.    strncat(nnthead, gp->name, name_length);                                     
  19958.    *(strchr(nnthead,'\0')) = ' ';                                               
  19959.    strcpy(nnthead + 79 - strlen(rowmessage), rowmessage);                       
  19960.                                                                                 
  19961.    (void)NNMivput(np,"NNTCMD " , tcmd,    -1);                                  
  19962.    (void)NNMivput(np,"NNTHEAD ", nnthead, -1);                                  
  19963.    (void)NNMivput(np,"NNTDYNA ", nntdyna, dynsize);                             
  19964.    prc = NNMdispl(np,"NNMDAR  ");                                               
  19965.    if (prc > 8) break;                                                          
  19966.    /*                                                                           
  19967.     * (void)NNMispf(np,"VGET (ZVERB ZSCROLLA ZSCROLLN)");                       
  19968.     */                                                                          
  19969.    (void)NNMivget(np,"NNTDYNA " , nntdyna,  dynsize);                           
  19970.    (void)NNMivget(np,"ZVERB "   , zverb,    sizeof(zverb));                     
  19971.    (void)NNMivget(np,"ZSCROLLA ", zscrolla, sizeof(zscrolla));                  
  19972.    zscrolln = NNMiget(np,"ZSCROLLN ");                                          
  19973.    nntlvl   = NNMiget(np,"NNTLVL ");                                            
  19974.    scroll   = 0;                                                                
  19975.                                                                                 
  19976.    /* Process selections. */                                                    
  19977.                                                                                 
  19978.    save_top_article = np->top_article;                                          
  19979.    np->top_article  = NULL;                                                     
  19980.                                                                                 
  19981.    for (ndp = ntdynarray_start, rowp = nntdyna;                                 
  19982.         ndp < ntdynarray_end && !np->quit;                                      
  19983.         ndp++,                  rowp += rowbump) {                              
  19984.      ap = ndp->article;                                                         
  19985.      sel = toupper(rowp[1]);                                                    
  19986.      if (sel == ' ') continue;                                                  
  19987.      for (sdp = tdp->first_seldesc; sdp->selection_code != ' '; sdp++) {        
  19988.        if (sel == sdp->selection_code) {                                        
  19989.          selection_processed_ok = (sdp->selection_processor)(np,ap);            
  19990.          sdp = NULL;                                                            
  19991.          break;                                                                 
  19992.        }                                                                        
  19993.      }                                                                          
  19994.      if (sdp) {                                                                 
  19995.        ERR1("Unknown selection code.  Type one of the listed codes.");          
  19996.        selection_processed_ok = FALSE;                                          
  19997.      }                                                                          
  19998.      else {                                                                     
  19999.        if (selection_processed_ok) {                                            
  20000.          /* if (!np->top_article) np->top_article = ap; */                      
  20001.        }                                                                        
  20002.      }                                                                          
  20003.    }                                                                            
  20004.                                                                                 
  20005.    if (np->quit) break;                                                         
  20006.                                                                                 
  20007.    if (!np->top_article || !np->article_autoscroll)                             
  20008.       np->top_article = save_top_article;                                       
  20009.                                                                                 
  20010.    /* Process command if any. */                                                
  20011.                                                                                 
  20012.    strcpy(tcmd,"");                                                             
  20013.                                                                                 
  20014.    (void)NNMivget(np,tdp->command_variable,tcmd,sizeof(tcmd));                  
  20015.                                                                                 
  20016.    if (strcmp(tcmd,"") != 0) {                                                  
  20017.                                                                                 
  20018.      memset(command,' ',COMMANDSIZE);                                           
  20019.      command_index = 0;                                                         
  20020.      for (cp = tcmd; *cp && !isspace(*cp); cp++) {                              
  20021.        if (cp >= tcmd+COMMANDSIZE) {                                            
  20022.          ERR1("Unknown command name.");                                         
  20023.          command_processed_ok = FALSE;                                          
  20024.        }                                                                        
  20025.        command[command_index++] = toupper(*cp);                                 
  20026.      }                                                                          
  20027.      while (*cp && isspace(*cp)) cp++;                                          
  20028.                                                                                 
  20029.      for (cdp = tdp->first_cmddesc;                                             
  20030.           cdp->command_name[0] != ' ';                                          
  20031.           cdp++) {                                                              
  20032.        if (memcmp(command,cdp->command_name,COMMANDSIZE-1) == 0) {              
  20033.          command_processed_ok = (cdp->command_processor)(np,gp,cp);             
  20034.          cdp = NULL;                                                            
  20035.          break;                                                                 
  20036.        }                                                                        
  20037.      }                                                                          
  20038.                                                                                 
  20039.      if (cdp) {                                                                 
  20040.          ERR1("Unknown command name.");                                         
  20041.        command_processed_ok = FALSE;                                            
  20042.      }                                                                          
  20043.                                                                                 
  20044.      if (command_processed_ok) strcpy(tcmd,"");                                 
  20045.                                                                                 
  20046.    }                                                                            
  20047.                                                                                 
  20048.    if (np->quit) break;                                                         
  20049.                                                                                 
  20050.    /* Process scroll request if any. */                                         
  20051.                                                                                 
  20052.    switch (zscrolla[0]) {                                                       
  20053.      case 'P':                                                                  
  20054.      case 'H':                                                                  
  20055.      case 'C':                                                                  
  20056.      case 'D':  is_max = FALSE;                                                 
  20057.                 is_scroll_word = TRUE;                                          
  20058.                 break;                                                          
  20059.      case 'M':  is_max = TRUE;                                                  
  20060.                 break;                                                          
  20061.      default:   is_max = FALSE;                                                 
  20062.                 is_scroll_word = FALSE;                                         
  20063.                 break;                                                          
  20064.    }                                                                            
  20065.                                                                                 
  20066.    if      (EQUAL(zverb,"DOWN")) {                                              
  20067.      if (is_max)         {                                                      
  20068.                           np->top_article = PHONY_NEWS_ARTICLE;                 
  20069.                           scroll = -((nntlvl-1)/np->article_rows);              
  20070.                          }                                                      
  20071.      else                                                                       
  20072.      if (is_scroll_word)  scroll = zscrolln/rowincr;                            
  20073.      else                 scroll = zscrolln;                                    
  20074.    }                                                                            
  20075.    else if (EQUAL(zverb,"UP")) {                                                
  20076.      if (is_max)         {                                                      
  20077.                           np->top_article = NULL;                               
  20078.                           scroll = 0;                                           
  20079.                          }                                                      
  20080.      else                                                                       
  20081.      if (is_scroll_word)  scroll = -zscrolln/rowincr;                           
  20082.      else                 scroll = -zscrolln;                                   
  20083.    }                                                                            
  20084.    else scroll = 0;                                                             
  20085.                                                                                 
  20086.  } while (prc == 0);                                                            
  20087.                                                                                 
  20088.  FREEMAIN(nntdyna,"NNTDYNA buffer");                                            
  20089.  FREEMAIN(ntdynarray_start,"newsarticle dynamic area");                         
  20090.                                                                                 
  20091.  /* Update newsgroup fields after articles handled. */                          
  20092.                                                                                 
  20093.  /* gp->fake_first_article_number  = gp->real_first_article_number; */          
  20094.  if (gp->real_last_article_number > gp->fake_last_article_number)               
  20095.      gp->fake_last_article_number = gp->real_last_article_number;               
  20096.  gp->fake_article_count = gp->real_article_count;                               
  20097.  gp->fake_unread_count  = gp->real_unread_count;                                
  20098.                                                                                 
  20099.  if (np->article_error_found) *restartp = TRUE;                                 
  20100.  else return TRUE;                                                              
  20101.                                                                                 
  20102. }                                                                               
  20103.                                                                                 
  20104. /****** View articles. ***********************************************/         
  20105.                                                                                 
  20106. Bool                                                                            
  20107. NNMvar(np,gp)                                                                   
  20108. Rstruc nncb           *np;                                                      
  20109. Rstruc newsgroup      *gp;                                                      
  20110. {                                                                               
  20111.  Bool                 *restart = FALSE;                                         
  20112.                                                                                 
  20113.  np->top_article               = NULL;                                          
  20114.  np->repeat_find               = FALSE;                                         
  20115.  np->article_criterion_changed = TRUE;                                          
  20116.  *np->selsubj                  = '\0';                                          
  20117.                                                                                 
  20118.  if (np->sort_by_subject) {                                                     
  20119.    np->sort_by_subject = FALSE;                                                 
  20120.    NNMsort(np,gp);                                                              
  20121.  }                                                                              
  20122.                                                                                 
  20123.  do {                                                                           
  20124.    np->article_error_found = FALSE;                                             
  20125.    if (!view_articles(np,gp,&restart)) return FALSE;                            
  20126.  } while (restart);                                                             
  20127.                                                                                 
  20128.  return TRUE;                                                                   
  20129.                                                                                 
  20130. }                                                                               
  20131.                                                                                 
  20132. ./   ADD NAME=NNMVNG,SSI=01540034                                               
  20133.                                                                                 
  20134.  /********************************************************************/         
  20135.  /*                                                                  */         
  20136.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  20137.  /*                                                                  */         
  20138.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  20139.  /*                                                                  */         
  20140.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  20141.  /* including the implied warranties of merchantability and fitness, */         
  20142.  /* are expressly denied.                                            */         
  20143.  /*                                                                  */         
  20144.  /* Provided this copyright notice is included, this software may    */         
  20145.  /* be freely distributed and not offered for sale.                  */         
  20146.  /*                                                                  */         
  20147.  /* Changes or modifications may be made and used only by the maker  */         
  20148.  /* of same, and not further distributed.  Such modifications should */         
  20149.  /* be mailed to the author for consideration for addition to the    */         
  20150.  /* software and incorporation in subsequent releases.               */         
  20151.  /*                                                                  */         
  20152.  /********************************************************************/         
  20153.                                                                                 
  20154. #pragma  csect(code,  "NN@VNG  ")                                               
  20155. #pragma  csect(static,"NN$VNG  ")                                               
  20156. #include "nn.h"                                                                 
  20157.                                                                                 
  20158. struct ngdynarray {                                                             
  20159.                    struct newsgroup      *newsgroup;                            
  20160.                   };                                                            
  20161.                                                                                 
  20162. /****** Display newsgroups via ISPF dynamic area. ********************/         
  20163.                                                                                 
  20164. Bool                                                                            
  20165. NNMvng(np)                                                                      
  20166. Rstruc nncb           *np;                                                      
  20167. {                                                                               
  20168.  Rstruc newsgroup     *gp;                                                      
  20169.  Rstruc ngdynarray    *ndp;                                                     
  20170.  struct ngdynarray    *ngdynarray_address;                                      
  20171.  Rstruc tabledesc     *tdp;                                                     
  20172.  Rstruc seldesc       *sdp;                                                     
  20173.  Rstruc cmddesc       *cdp;                                                     
  20174.  char                 *cp;                                                      
  20175.  int                   next_offset;                                             
  20176.  int                   command_index;                                           
  20177.  int                   newsgroup_count;                                         
  20178.  int                   display_total;                                           
  20179.  int                   dti;                                                     
  20180.  int                   ngi;                                                     
  20181.  int                   prc;                                                     
  20182.  int                   nnglvl;                                                  
  20183.  int                   depth;                                                   
  20184.  int                   topgroup;                                                
  20185.  int                   bottomgroup;                                             
  20186.  int                   save_topgroup;                                           
  20187.  int                   last_group_selected;                                     
  20188.  int                   zscrolln;                                                
  20189.  int                   dynsize;                                                 
  20190.  int                   framelength;                                             
  20191.  int                   findbump;                                                
  20192.  int                   article_count;                                           
  20193.  int                   unread_count;                                            
  20194.  int                   first_article_number;                                    
  20195.  int                   last_article_number;                                     
  20196.  short                 name_length;                                             
  20197.  Bool                  is_max;                                                  
  20198.  Bool                  selection_processed_ok;                                  
  20199.  Bool                  command_processed_ok;                                    
  20200.  Bool                  text_not_found;                                          
  20201.  char                 *rowp;                                                    
  20202.  char                 *nngdyna;                                                 
  20203.  char                  sel;                                                     
  20204.  char                  tcmd     [72];                                           
  20205.  char                  nnghead  [81];                                           
  20206.  char                  nngline  [81];                                           
  20207.  char                  command  [COMMANDSIZE];                                  
  20208.  char                  zverb     [9];                                           
  20209.  char                  zscrolla  [9];                                           
  20210.  char                  rowmessage[81];                                          
  20211.                                                                                 
  20212.  static char           dashes[65] =                                             
  20213.     "----------------------------------------------------------------";         
  20214.                                                                                 
  20215.  tdp = np->newsgroup_display_table_address;                                     
  20216.                                                                                 
  20217.  np->current_newsgroup           = NULL;                                        
  20218.  np->newsgroup_selected          = FALSE;                                       
  20219.  np->newsgroup_criterion_changed = TRUE;                                        
  20220.  np->newsgroup_order_changed     = TRUE;                                        
  20221.  text_not_found                  = FALSE;                                       
  20222.  strcpy(np->only_string,"");                                                    
  20223.                                                                                 
  20224.  /* Determine how many TOTAL newsgroups we have. */                             
  20225.                                                                                 
  20226.  newsgroup_count = 0;                                                           
  20227.  for (gp = np->first_newsgroup; gp; gp = gp->next) newsgroup_count++;           
  20228.                                                                                 
  20229.  /* Allocate a block of "ngdynarray" newsgroup pointers, one element            
  20230.   * for each newsgroup that is currently displayed.  This must be               
  20231.   * big enough to hold all known newsgroups at maximum.                         
  20232.   */                                                                            
  20233.                                                                                 
  20234.  if (newsgroup_count == 0) {                                                    
  20235.    ERR1(                                                                        
  20236.      "No newsgroups to display.  Use L option to get list from server."         
  20237.        );                                                                       
  20238.    return FALSE;                                                                
  20239.  }                                                                              
  20240.                                                                                 
  20241.  GETMAIN(ngdynarray_address, struct ngdynarray,                                 
  20242.          newsgroup_count, "newsgroup dynamic array");                           
  20243.  if (!ngdynarray_address) return FALSE;                                         
  20244.                                                                                 
  20245.  /* Get depth of dynamic area (number of rows to display on screen) */          
  20246.                                                                                 
  20247.  (void)NNMispf(np,                                                              
  20248.        "PQUERY PANEL(NNMDNG) AREANAME(NNGDYNA) DEPTH(NNGDEPTH)");               
  20249.  if (np->ispfrc != 0) return FALSE;                                             
  20250.  depth = NNMiget(np,"NNGDEPTH ");                                               
  20251.                                                                                 
  20252.  /* Get storage for ISPF dynamic area variable to be constructed. */            
  20253.                                                                                 
  20254.  dynsize = 80*depth;                                                            
  20255.  GETMAIN(nngdyna, char, dynsize, "NNGDYNA buffer");                             
  20256.  if (!nngdyna) return FALSE;                                                    
  20257.  memset(nngdyna,' ',dynsize);                                                   
  20258.                                                                                 
  20259.  topgroup = 0;                                                                  
  20260.                                                                                 
  20261.  strcpy(tcmd,"");                                                               
  20262.                                                                                 
  20263.  memset(nngline,' ',80);                                                        
  20264.  nngline[ 0] = DATAOUT_HIGH;                                                    
  20265.  nngline[ 1] = 'S';                                                             
  20266.  nngline[ 2] = DATAOUT_LOW;                                                     
  20267.  memcpy(&nngline[ 3],"select",6);                                               
  20268.  nngline[ 9] = DATAOUT_HIGH;                                                    
  20269.  nngline[10] = 'A';                                                             
  20270.  nngline[11] = DATAOUT_LOW;                                                     
  20271.  memcpy(&nngline[12],"all",   3);                                               
  20272.  nngline[15] = DATAOUT_HIGH;                                                    
  20273.  nngline[16] = 'R';                                                             
  20274.  nngline[17] = DATAOUT_LOW;                                                     
  20275.  memcpy(&nngline[18],"reg",   3);                                               
  20276.  nngline[21] = DATAOUT_HIGH;                                                    
  20277.  nngline[22] = 'D';                                                             
  20278.  nngline[23] = DATAOUT_LOW;                                                     
  20279.  memcpy(&nngline[24],"dereg", 5);                                               
  20280.  nngline[29] = DATAOUT_HIGH;                                                    
  20281.  nngline[30] = 'M';                                                             
  20282.  nngline[31] = DATAOUT_LOW;                                                     
  20283.  memcpy(&nngline[32],"mark",  4);                                               
  20284.  nngline[36] = DATAOUT_HIGH;                                                    
  20285.  nngline[37] = 'U';                                                             
  20286.  nngline[38] = DATAOUT_LOW;                                                     
  20287.  memcpy(&nngline[39],"unmark",6);                                               
  20288.  nngline[48] = DATAOUT_HIGH;                                                    
  20289.  strcpy(&nngline[49],"Unread   Count   Range");                                 
  20290.                                                                                 
  20291.  /* The last line above may be variable some day if we have to vary             
  20292.   * the width of the numbers...                                                 
  20293.   */                                                                            
  20294.                                                                                 
  20295.  /* Loop displaying newsgroups until END or criterion changed. */               
  20296.                                                                                 
  20297.  do {                                                                           
  20298.                                                                                 
  20299.    /* If the newsgroup display criteria have changed, or this is the            
  20300.     * first time through, build the array of newsgroup pointers.                
  20301.     */                                                                          
  20302.                                                                                 
  20303.    if (np->newsgroup_criterion_changed || np->newsgroup_order_changed) {        
  20304.      ndp = ngdynarray_address;                                                  
  20305.      display_total = 0;                                                         
  20306.      topgroup = 0;                                                              
  20307.      switch (np->newsgroup_order) {                                             
  20308.        case NNTP_LIST_ORDER:                                                    
  20309.             gp = np->first_newsgroup_alt;                                       
  20310.             next_offset = (char *)&gp->next2 - (char *)gp;                      
  20311.             break;                                                              
  20312.        case ALPHABETICAL_ORDER:                                                 
  20313.        default:                                                                 
  20314.             gp = np->first_newsgroup;                                           
  20315.             next_offset = (char *)&gp->next - (char *)gp;                       
  20316.             break;                                                              
  20317.      }                                                                          
  20318.      for (; gp; gp = *(struct newsgroup **)((int)gp + next_offset)) {           
  20319.        if (np->newsgroup_criterion_changed) {                                   
  20320.          OffGroupInTable(gp);   /* guilty until proven innocent */              
  20321.          if ((np->show_all_newsgroups && !NoSuchGroup(gp))                      
  20322.           || gp->registered) {                                                  
  20323.            if (!*np->only_string || strstr(gp->name,np->only_string)) {         
  20324.              SetGroupInTable(gp);                                               
  20325.            }                                                                    
  20326.          }                                                                      
  20327.        }                                                                        
  20328.        if (GroupInTable(gp)) {                                                  
  20329.          display_total++;                                                       
  20330.          ndp->newsgroup = gp;                                                   
  20331.          ndp++;                                                                 
  20332.        }                                                                        
  20333.      }                                                                          
  20334.    }                                                                            
  20335.                                                                                 
  20336.    np->newsgroup_criterion_changed = FALSE;                                     
  20337.    np->newsgroup_order_changed     = FALSE;                                     
  20338.                                                                                 
  20339.    /* Fill dynamic area with data for groups satisfying criterion. */           
  20340.                                                                                 
  20341.    memset(nngdyna, ' ', dynsize);                                               
  20342.                                                                                 
  20343.    for (dti = 0,       ngi = topgroup,        rowp = nngdyna;                   
  20344.         dti < depth && ngi < display_total;                                     
  20345.         dti++,         ngi++,                 rowp += 80) {                     
  20346.      ndp = &ngdynarray_address[ngi];                                            
  20347.      gp = ndp->newsgroup;                                                       
  20348.      if (gp->real_article_count == NO_VALUE)                                    
  20349.           article_count        = gp->fake_article_count;                        
  20350.      else article_count        = gp->real_article_count;                        
  20351.      if (gp->real_unread_count == NO_VALUE)                                     
  20352.           unread_count         = gp->fake_unread_count;                         
  20353.      else unread_count         = gp->real_unread_count;                         
  20354.      if (gp->real_first_article_number == NO_VALUE)                             
  20355.           first_article_number = gp->fake_first_article_number;                 
  20356.      else first_article_number = gp->real_first_article_number;                 
  20357.      if (gp->real_last_article_number == NO_VALUE)                              
  20358.           last_article_number  = gp->fake_last_article_number;                  
  20359.      else last_article_number  = gp->real_last_article_number;                  
  20360.      rowp[ 0]       = DATAIN_HIGH;     /* selection code attribute */           
  20361.      rowp[ 1]       = ' ';             /* selection code field     */           
  20362.      rowp[ 2]       = gp->registered                                            
  20363.                       ? (unread_count ? DATAOUT_YELLOW : DATAOUT_TURQ)          
  20364.                       : (unread_count ? DATAOUT_GREEN  : DATAOUT_BLUE);         
  20365.                                         /* newsgroup name attribute */          
  20366.      memset(&rowp[3], '.', 40);                                                 
  20367.      name_length = strlen(gp->name);                                            
  20368.      if (name_length > 40) name_length = 40;                                    
  20369.      memcpy(&rowp[3], gp->name, name_length);                                   
  20370.      rowp[3+name_length] = DATAOUT_BLUE;                                        
  20371.      rowp[43] = DATAOUT_PINK;                                                   
  20372.      rowp[44] = gp->registered ? 'R' : ' ';                                     
  20373.      rowp[45] = DATAOUT_HIGH;                                                   
  20374.      if (unread_count > 0)                                                      
  20375.         sprintf(&rowp[46], "  %7d", unread_count);                              
  20376.      rowp[55] = DATAOUT_LOW;                                                    
  20377.      if (article_count == 0)                                                    
  20378.         strcpy(&rowp[56],"      0                ");                            
  20379.      else                                                                       
  20380.         sprintf(&rowp[56], "%7d %7d -%7d",                                      
  20381.                            article_count,                                       
  20382.                            first_article_number,                                
  20383.                            last_article_number);                                
  20384.      rowp[strlen(rowp)] = ' ';                                                  
  20385.                                                                                 
  20386.      if (NoSuchGroup(gp)) {                                                     
  20387.        memcpy(&rowp[46],"******* No such newsgroup *******",33);                
  20388.      }                                                                          
  20389.                                                                                 
  20390.    }                                                                            
  20391.                                                                                 
  20392.    if (rowp < nngdyna + dynsize) {                                              
  20393.      rowp[0] = DATAOUT_HIGH;                                                    
  20394.      memset(&rowp[1], '-',79);                                                  
  20395.    }                                                                            
  20396.                                                                                 
  20397.    bottomgroup = ngi - 1;                                                       
  20398.                                                                                 
  20399.    if (topgroup > bottomgroup) strcpy(rowmessage,"");                           
  20400.    else sprintf(rowmessage, "%d-%d of %d",                                      
  20401.                        topgroup + 1, bottomgroup + 1, display_total);           
  20402.                                                                                 
  20403.                                                                                 
  20404.    framelength = (79 - strlen(rowmessage) - sizeof("Newsgroup Listing")         
  20405.                  - 3) / 2;                                                      
  20406.                                                                                 
  20407.    sprintf(nnghead, "%*.*s Newsgroup Listing %*.*s %s",                         
  20408.                     framelength, framelength, dashes,                           
  20409.                     framelength, framelength, dashes,                           
  20410.                     rowmessage);                                                
  20411.                                                                                 
  20412.    (void)NNMivput(np,"NNGCMD ",  tcmd,    -1);                                  
  20413.    (void)NNMivput(np,"NNGHEAD ", nnghead, -1);                                  
  20414.    (void)NNMivput(np,"NNGLINE ", nngline, -1);                                  
  20415.    (void)NNMivput(np,"NNGDYNA ", nngdyna, dynsize);                             
  20416.    prc = NNMdispl(np,"NNMDNG  ");                                               
  20417.    if (prc > 8) break;                                                          
  20418.    /*                                                                           
  20419.     * (void)NNMispf(np,"VGET (ZVERB ZSCROLLA ZSCROLLN)");                       
  20420.     */                                                                          
  20421.    (void)NNMivget(np,"NNGDYNA " , nngdyna,  dynsize);                           
  20422.    (void)NNMivget(np,"ZVERB "   , zverb,    sizeof(zverb));                     
  20423.    (void)NNMivget(np,"ZSCROLLA ", zscrolla, sizeof(zscrolla));                  
  20424.    zscrolln = NNMiget(np,"ZSCROLLN ");                                          
  20425.    nnglvl   = NNMiget(np,"NNGLVL ");                                            
  20426.                                                                                 
  20427.    /* Initialize what may be set by selection/command processors. */            
  20428.                                                                                 
  20429.    strcpy(np->nngroup,"");                                                      
  20430.    last_group_selected = -1;                                                    
  20431.    np->please_locate_group = FALSE;                                             
  20432.    np->please_find_group   = FALSE;                                             
  20433.                                                                                 
  20434.    /* Process selections. */                                                    
  20435.                                                                                 
  20436.    for (ngi = topgroup,        rowp = nngdyna;                                  
  20437.         ngi <= bottomgroup  && !np->quit;                                       
  20438.         ngi++,                 rowp += 80) {                                    
  20439.      ndp = &ngdynarray_address[ngi];                                            
  20440.      gp = ndp->newsgroup;                                                       
  20441.      sel = toupper(rowp[1]);                                                    
  20442.      if (sel == ' ') continue;                                                  
  20443.      for (sdp = tdp->first_seldesc; sdp->selection_code != ' '; sdp++) {        
  20444.        if (sel == sdp->selection_code) {                                        
  20445.          (void)NNMivput(np,"NNGNAME ",gp->name, -1);                            
  20446.          selection_processed_ok = (sdp->selection_processor)(np,gp);            
  20447.          sdp = NULL;                                                            
  20448.          break;                                                                 
  20449.        }                                                                        
  20450.      }                                                                          
  20451.      if (sdp) {                                                                 
  20452.        ERR1("Unknown selection code.  Type one of the listed codes.");          
  20453.        selection_processed_ok = FALSE;                                          
  20454.      }                                                                          
  20455.      else if (selection_processed_ok) {                                         
  20456.        /* topgroup = ngi; */                                                    
  20457.        if (*np->nngroup) last_group_selected = ngi;                             
  20458.      }                                                                          
  20459.    }                                                                            
  20460.                                                                                 
  20461.    if (np->quit) break;                                                         
  20462.                                                                                 
  20463.    /* Process command if any. */                                                
  20464.                                                                                 
  20465.    strcpy(tcmd,"");                                                             
  20466.                                                                                 
  20467.    (void)NNMivget(np,tdp->command_variable,tcmd,sizeof(tcmd));                  
  20468.                                                                                 
  20469.    if (strcmp(tcmd,"") != 0) {                                                  
  20470.                                                                                 
  20471.      memset(command,' ',COMMANDSIZE);                                           
  20472.      command_index = 0;                                                         
  20473.      for (cp = tcmd; *cp && !isspace(*cp); cp++) {                              
  20474.        if (cp >= tcmd+COMMANDSIZE) {                                            
  20475.          ERR1("Unknown command name.");                                         
  20476.          command_processed_ok = FALSE;                                          
  20477.        }                                                                        
  20478.        command[command_index++] = toupper(*cp);                                 
  20479.      }                                                                          
  20480.      while (*cp && isspace(*cp)) cp++;                                          
  20481.                                                                                 
  20482.      for (cdp = tdp->first_cmddesc;                                             
  20483.           cdp->command_name[0] != ' ';                                          
  20484.           cdp++) {                                                              
  20485.        if (memcmp(command,cdp->command_name,COMMANDSIZE-1) == 0) {              
  20486.          command_processed_ok = (cdp->command_processor)(np,NULL,cp);           
  20487.          cdp = NULL;                                                            
  20488.          break;                                                                 
  20489.        }                                                                        
  20490.      }                                                                          
  20491.                                                                                 
  20492.      if (cdp) {                                                                 
  20493.        ERR1("Unknown command name.");                                           
  20494.        command_processed_ok = FALSE;                                            
  20495.      }                                                                          
  20496.                                                                                 
  20497.      if (command_processed_ok) strcpy(tcmd,"");                                 
  20498.                                                                                 
  20499.    }                                                                            
  20500.                                                                                 
  20501.    if (np->quit) break;                                                         
  20502.                                                                                 
  20503.    /* If locate to a specific group name was requested,                         
  20504.     * process before any scroll request.                                        
  20505.     */                                                                          
  20506.                                                                                 
  20507.    if (last_group_selected >= 0 && np->newsgroup_autoscroll) {                  
  20508.      text_not_found = FALSE;                                                    
  20509.      topgroup = last_group_selected;                                            
  20510.    }                                                                            
  20511.    else if (np->please_locate_group) {                                          
  20512.      text_not_found = FALSE;                                                    
  20513.      for (topgroup = 0, ndp = ngdynarray_address;                               
  20514.           topgroup < display_total;                                             
  20515.           topgroup++,   ndp++) {                                                
  20516.        gp = ndp->newsgroup;                                                     
  20517.        if (strcmp(gp->name,np->locate_string) >= 0) break;                      
  20518.      }                                                                          
  20519.      if (topgroup == display_total) topgroup--;                                 
  20520.    }                                                                            
  20521.    else if (np->please_find_group) {                                            
  20522.      save_topgroup = topgroup;                                                  
  20523.      switch (np->find_option) {                                                 
  20524.        case FIND_NEXT:                                                          
  20525.                        findbump = 1;                                            
  20526.                        if (np->repeat_find) {                                   
  20527.                          if (text_not_found) topgroup = 0;                      
  20528.                          else topgroup++;                                       
  20529.                        }                                                        
  20530.                        break;                                                   
  20531.        case FIND_PREV:                                                          
  20532.                        findbump = -1;                                           
  20533.                        if (np->repeat_find) {                                   
  20534.                          if (text_not_found) topgroup = bottomgroup;            
  20535.                          else topgroup--;                                       
  20536.                        }                                                        
  20537.                        break;                                                   
  20538.        case FIND_FIRST:                                                         
  20539.                        topgroup = 0;                                            
  20540.                        findbump = 1;                                            
  20541.                        break;                                                   
  20542.        case FIND_LAST:                                                          
  20543.                        topgroup = display_total - 1;                            
  20544.                        findbump = -1;                                           
  20545.                        break;                                                   
  20546.      }                                                                          
  20547.      gp = NULL;                                                                 
  20548.      for (ndp = &ngdynarray_address[topgroup];                                  
  20549.           topgroup < display_total && topgroup >= 0;                            
  20550.           topgroup += findbump, ndp += findbump) {                              
  20551.        if (GroupInTable(ndp->newsgroup)                                         
  20552.         && strstr(ndp->newsgroup->name,np->find_string)) {                      
  20553.          gp = ndp->newsgroup;                                                   
  20554.          break;                                                                 
  20555.        }                                                                        
  20556.      }                                                                          
  20557.      if (!gp) {                                                                 
  20558.        topgroup = save_topgroup;                                                
  20559.        text_not_found = TRUE;                                                   
  20560.        ERR3("No %s newsgroups with '%s' in name.",                              
  20561.             (findbump > 0 ? "more" : "previous"),                               
  20562.             np->find_string);                                                   
  20563.      }                                                                          
  20564.      else {                                                                     
  20565.        text_not_found = FALSE;                                                  
  20566.    WARN1("Newsgroup found;\                                                     
  20567. The newsgroup whose name contains the desired text tops the display.");         
  20568.      }                                                                          
  20569.    }                                                                            
  20570.    else text_not_found = FALSE;                                                 
  20571.                                                                                 
  20572.    /* Process scroll request if any. */                                         
  20573.                                                                                 
  20574.    is_max = EQUAL(zscrolla,"MAX");                                              
  20575.    if      (EQUAL(zverb,"DOWN")) {                                              
  20576.      if (is_max) topgroup = display_total - nnglvl + 1;                         
  20577.      else        topgroup += zscrolln;                                          
  20578.    }                                                                            
  20579.    else if (EQUAL(zverb,"UP")) {                                                
  20580.      if (is_max) topgroup = 0;                                                  
  20581.      else        topgroup -= zscrolln;                                          
  20582.    }                                                                            
  20583.    if (topgroup < 0)                                                            
  20584.        topgroup = 0;                                                            
  20585.    if (topgroup > display_total)                                                
  20586.        topgroup = display_total;                                                
  20587.                                                                                 
  20588.  } while (prc == 0);                                                            
  20589.                                                                                 
  20590.  FREEMAIN(nngdyna,"NNGDYNA buffer");                                            
  20591.  FREEMAIN(ngdynarray_address,"newsgroup dynamic area");                         
  20592.                                                                                 
  20593.  return TRUE;                                                                   
  20594.                                                                                 
  20595. }                                                                               
  20596.                                                                                 
  20597. ./   ADD NAME=NNMVTX,SSI=01150048                                               
  20598.                                                                                 
  20599.  /********************************************************************/         
  20600.  /*                                                                  */         
  20601.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  20602.  /*                                                                  */         
  20603.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  20604.  /*                                                                  */         
  20605.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  20606.  /* including the implied warranties of merchantability and fitness, */         
  20607.  /* are expressly denied.                                            */         
  20608.  /*                                                                  */         
  20609.  /* Provided this copyright notice is included, this software may    */         
  20610.  /* be freely distributed and not offered for sale.                  */         
  20611.  /*                                                                  */         
  20612.  /* Changes or modifications may be made and used only by the maker  */         
  20613.  /* of same, and not further distributed.  Such modifications should */         
  20614.  /* be mailed to the author for consideration for addition to the    */         
  20615.  /* software and incorporation in subsequent releases.               */         
  20616.  /*                                                                  */         
  20617.  /********************************************************************/         
  20618.                                                                                 
  20619. #pragma  csect(code,  "NN@VTX  ")                                               
  20620. #pragma  csect(static,"NN$VTX  ")                                               
  20621. #include "nn.h"                                                                 
  20622.                                                                                 
  20623. /****** BRIF fakeout. ************************************************/         
  20624.                                                                                 
  20625. static void                                                                     
  20626. fake_out_for_brif(fpp,codebuf)                                                  
  20627. void **fpp;                                                                     
  20628. char  *codebuf;                                                                 
  20629.                                                                                 
  20630. #ifndef I370                                                                    
  20631.                                                                                 
  20632. /* The purpose of this is to put a wrapper around the actual                    
  20633.    function pointed to by the argument, so that FORTRAN-style                   
  20634.    return codes (in register 0) get put into register 15.                       
  20635.                                                                                 
  20636.    Source code:                                                                 
  20637.                                                                                 
  20638.          USING *,15                                                             
  20639.          ST    14,save_14                                                       
  20640.          L     15,realcode                                                      
  20641.          DROP  15                                                               
  20642.          BALR  14,15                                                            
  20643.          USING *,14                                                             
  20644.          L     14,save_14                                                       
  20645.          DROP  14                                                               
  20646.          LR    15,0                                                             
  20647.          BR    14                                                               
  20648.          SPACE 1                                                                
  20649. save_14  DS    F                                                                
  20650. realcode DS    F                                                                
  20651.                                                                                 
  20652.  *** Warning: As written, this fake-out code is not reentrant. ***              
  20653.                                                                                 
  20654. */                                                                              
  20655.                                                                                 
  20656. {                                                                               
  20657.  static char fake_out_code[32] = {                                              
  20658.                                0x50,0xE0,0xF0,0x14,0x58,0xF0,0xF0,0x18,         
  20659.                                0x05,0xEF,0x58,0xE0,0xE0,0x0A,0x18,0xF0,         
  20660.                                0x07,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,         
  20661.                                0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00          
  20662.                                  };                                             
  20663.                                                                                 
  20664.  memcpy(codebuf,fake_out_code,32);                                              
  20665.  memcpy(codebuf+0x18,(char *)fpp,4);                                            
  20666.                                                                                 
  20667. #else                                                                           
  20668.                                                                                 
  20669. /* The purpose of this is to put a wrapper around the actual                    
  20670.    function pointed to by the argument, so that the C Runtime                   
  20671.    Anchor Block pointer (in register 12) can be saved/restored.                 
  20672. */                                                                              
  20673.                                                                                 
  20674. {                                                                               
  20675. #define FAKE_BUF_SIZE 48               /*                             */        
  20676.  static short fake_out_code[FAKE_BUF_SIZE/2] =                                  
  20677.  {                                     /*     USING *,15              */        
  20678.   0x50C0,0xF020,                       /* +00 ST    14,save_12        */        
  20679.   0x50E0,0xF024,                       /* +04 ST    12,save_14        */        
  20680.   0x58C0,0xF02C,                       /* +08 L     12,crab           */        
  20681.   0x58F0,0xF028,                       /* +0C L     15,realcode       */        
  20682.                                        /*     DROP  15                */        
  20683.   0x58F0,0xF000,                       /* +10 L     15,0(,15)         */        
  20684.   0x05EF,                              /* +14 BALR  14,15             */        
  20685.                                        /*     USING *,14              */        
  20686.   0x58C0,0xE00A,                       /* +16 L     12,save_12        */        
  20687.   0x58E0,0xE00E,                       /* +1A L     14,save_14        */        
  20688.                                        /*     DROP  14                */        
  20689.   0x07FE,                              /* +1E BR    14                */        
  20690.   0x0000,0x0000,                       /* +20 save_12                 */        
  20691.   0x0000,0x0000,                       /* +24 save_14                 */        
  20692.   0x0000,0x0000,                       /* +28 realcode                */        
  20693.   0x0000,0x0000                        /* +2C crab                    */        
  20694.  };                                                                             
  20695.                                                                                 
  20696.  memcpy( codebuf, fake_out_code, FAKE_BUF_SIZE );                               
  20697.  memcpy( codebuf+0x28, (char *)fpp, 4 );                                        
  20698.  _ldregs( R2, codebuf+0x2C  ),         /* get -> crab in fakeout buff */        
  20699.  _code  ( 0, 0x50C0, 0x2000 );         /* save -> CRAB                */        
  20700.                                                                                 
  20701. #endif                                                                          
  20702.                                                                                 
  20703.  *fpp = (void *)codebuf;                                                        
  20704.                                                                                 
  20705.  return;                                                                        
  20706.                                                                                 
  20707. }                                                                               
  20708.                                                                                 
  20709. /****** Print text lines. ********************************************/         
  20710.                                                                                 
  20711. static void                                                                     
  20712. print_text_lines(fp,textp)                                                      
  20713. FILE              *fp;                                                          
  20714. struct textline   *textp;                                                       
  20715. {                                                                               
  20716.  struct textline  *tp;                                                          
  20717.  char             *p;                                                           
  20718.                                                                                 
  20719.  for (tp=textp; tp; tp=tp->next) {                                              
  20720.    if (tp->text_length >= 0) {                                                  
  20721.      p = tp->tab_expanded_text;                                                 
  20722.      while (*p) {                                                               
  20723.        if isprint(*p) fprintf(fp,"%c",*p);                                      
  20724.        else fprintf(fp,"?");                                                    
  20725.        p++;                                                                     
  20726.      }                                                                          
  20727.      fprintf(fp,"\n");                                                          
  20728.    }                                                                            
  20729.  }                                                                              
  20730.  fprintf(fp,"\n");                                                              
  20731.                                                                                 
  20732.  return;                                                                        
  20733. }                                                                               
  20734.                                                                                 
  20735. /****** View the lines of text retrieved from the server. ************/         
  20736.                                                                                 
  20737. void                                                                            
  20738. NNMvtx(np,gp,ap)                                                                
  20739. Rstruc nncb         *np;                                                        
  20740. Rstruc newsgroup    *gp;                                                        
  20741. Rstruc newsarticle  *ap;                                                        
  20742. {                                                                               
  20743.  int                brif_max_reclen;                                            
  20744.  struct texthdr    *texthdrp;                                                   
  20745.  void              *dialog_data_ptr;                                            
  20746.  void              *read_function_ptr;                                          
  20747.  void              *command_function_ptr;                                       
  20748.  char               read_fakeout_buffer    [32];                                
  20749.  char               command_fakeout_buffer [32];                                
  20750.  char               brif_title             [81];                                
  20751.                                                                                 
  20752.  /* If article is not specified, use main nncb, else article's text */          
  20753.                                                                                 
  20754.  texthdrp = (ap ? &ap->thdr : &np->thdr);                                       
  20755.                                                                                 
  20756.  if (np->brifp) {                                                               
  20757.    printf("Cannot use ISPF BROWSE now, displaying in line mode:\n\n");          
  20758.    print_text_lines(stdout,texthdrp->first_text_line);                          
  20759.    return;                                                                      
  20760.  }                                                                              
  20761.                                                                                 
  20762.  np->brifp = texthdrp;                                                          
  20763.                                                                                 
  20764.  if (np->batch_mode) {                                                          
  20765.    NNMbtext(np,np->brifp,NULL);                                                 
  20766.    np->brifp = NULL;                                                            
  20767.    return;                                                                      
  20768.  }                                                                              
  20769.                                                                                 
  20770.  np->brif_previous_recno = -1;                                                  
  20771.  np->article_being_viewed  = ap;                                                
  20772.                                                                                 
  20773.  if (ap) sprintf(brif_title, "%s:%d ",        gp->name, ap->number);            
  20774.  else    sprintf(brif_title, "NewsServer:%s ",np->nnserver);                    
  20775.                                                                                 
  20776.  brif_max_reclen      = np->brifp->text_max_tab_expanded_length;                
  20777.  dialog_data_ptr      = (void *)np;                                             
  20778.  read_function_ptr    = (void *)&NNMbrifr;                                      
  20779.  command_function_ptr = (void *)&NNMbrifc;                                      
  20780.                                                                                 
  20781.  fake_out_for_brif(&read_function_ptr,read_fakeout_buffer);                     
  20782.  fake_out_for_brif(&command_function_ptr,command_fakeout_buffer);               
  20783.                                                                                 
  20784.  if (np->test_mode) {                                                           
  20785.    printf("Here are the %d lines BRIF should be displaying:\n\n",               
  20786.           np->brifp->text_line_count);                                          
  20787.    print_text_lines(stdout,np->brifp->first_text_line);                         
  20788.    np->brifp = NULL;                                                            
  20789.    return;                                                                      
  20790.  }                                                                              
  20791.                                                                                 
  20792.  if (np->setmsg) {                                                              
  20793.    (void)NNMispf(np,"SETMSG MSG(ISRZ002)");                                     
  20794.    np->setmsg = FALSE;                                                          
  20795.  }                                                                              
  20796.                                                                                 
  20797.  np->ispfrc = ISPLINK("BRIF ",                                                  
  20798.                       brif_title,                                               
  20799.                       "V ",              /* variable record format */           
  20800.                       &brif_max_reclen,                                         
  20801.                       &read_function_ptr,                                       
  20802.                       &command_function_ptr,                                    
  20803.                       &dialog_data_ptr,                                         
  20804.                       "NNMBROBF",        /* use NNMVS's browse panel */         
  20805.                       "        ",        /* no format */                        
  20806.                       "NO ");            /* default sbcs data */                
  20807.                                                                                 
  20808.  np->brifp = NULL;                                                              
  20809.                                                                                 
  20810.  switch (np->ispfrc) {                                                          
  20811.    case  0:                                                                     
  20812.            break;                                                               
  20813.    case 12:                                                                     
  20814.  ERR1("There is no data returned from the news server to be browsed.");         
  20815.            break;                                                               
  20816.    case 16:                                                                     
  20817.            break;                                                               
  20818.    default:                                                                     
  20819.            NNMierr(np);   /* handle ISPF error */                               
  20820.            break;                                                               
  20821.  }                                                                              
  20822.                                                                                 
  20823.  return;                                                                        
  20824. }                                                                               
  20825.                                                                                 
  20826. ./   ADD NAME=NNMXARTT,SSI=011E0012                                             
  20827.                                                                                 
  20828.  /********************************************************************/         
  20829.  /*                                                                  */         
  20830.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  20831.  /*                                                                  */         
  20832.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  20833.  /*                                                                  */         
  20834.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  20835.  /* including the implied warranties of merchantability and fitness, */         
  20836.  /* are expressly denied.                                            */         
  20837.  /*                                                                  */         
  20838.  /* Provided this copyright notice is included, this software may    */         
  20839.  /* be freely distributed and not offered for sale.                  */         
  20840.  /*                                                                  */         
  20841.  /* Changes or modifications may be made and used only by the maker  */         
  20842.  /* of same, and not further distributed.  Such modifications should */         
  20843.  /* be mailed to the author for consideration for addition to the    */         
  20844.  /* software and incorporation in subsequent releases.               */         
  20845.  /*                                                                  */         
  20846.  /********************************************************************/         
  20847.                                                                                 
  20848. #pragma  csect(code,  "NN@XARTT")                                               
  20849. #pragma  csect(static,"NN$XARTT")                                               
  20850. #include "nn.h"                                                                 
  20851.                                                                                 
  20852. /****** Extract article titles. **************************************/         
  20853.                                                                                 
  20854. Bool                                                                            
  20855. NNMxartt(np,gp)                                                                 
  20856. Rstruc nncb         *np;                                                        
  20857. Rstruc newsgroup    *gp;                                                        
  20858. {                                                                               
  20859.  Rstruc newsarticle *ap;                                                        
  20860.  FILE               *xfp;                                                       
  20861.  char               *stat;                                                      
  20862.  struct extraction  *ep;                                                        
  20863.  struct extraction   the_extraction;                                            
  20864.  struct countdown    cd;                                                        
  20865.                                                                                 
  20866.  if (!gp->first_article) {                                                      
  20867.    ERR2("Newsgroup %s contains no articles.",gp->name);                         
  20868.    return FALSE;                                                                
  20869.  }                                                                              
  20870.                                                                                 
  20871.  /* Display panel asking for data set name into which to extract. */            
  20872.                                                                                 
  20873.  ep = &the_extraction;                                                          
  20874.  memset(ep,0,sizeof(struct extraction));                                        
  20875.  ep->mode = SEQ;                                                                
  20876.  strcpy(ep->panelname,"NNMPEXN1");                                              
  20877.                                                                                 
  20878.  if (!((xfp=NNMgetds(np,ep)))) return TRUE;                                     
  20879.                                                                                 
  20880.  /* If append mode, and a separator line was specified, use it. */              
  20881.                                                                                 
  20882.  if (ep->appending && *ep->separator) {                                         
  20883.    fprintf(xfp,"%s\n",ep->separator);                                           
  20884.    if (ep->blanking) fprintf(xfp,"\n");                                         
  20885.  }                                                                              
  20886.                                                                                 
  20887.  fprintf(xfp," Newsgroup: %-43.43s       Status   Date\n\n", gp->name);         
  20888.                                                                                 
  20889.  cd.do_update = (np->updatefreq >= 0);                                          
  20890.  cd.done      = 0;                                                              
  20891.  cd.to_do     = 0;                                                              
  20892.                                                                                 
  20893.  if (cd.do_update) {                                                            
  20894.    for (ap = gp->first_article; ap <= gp->fake_last_article; ap++) {            
  20895.      if (ArticleInTable(ap)) cd.to_do++;                                        
  20896.    }                                                                            
  20897.  }                                                                              
  20898.                                                                                 
  20899.  /* Retrieve all headers before proceeding. */                                  
  20900.                                                                                 
  20901.  ap = gp->first_article;                                                        
  20902.  while (ap <= gp->fake_last_article) {                                          
  20903.    if (ArticleInTable(ap)) {    /* Only articles currently in table */          
  20904.      if (!NNMrarh(np,gp,ap,TRUE,&cd)) {  /* Retrieve article header */          
  20905.        fprintf(stderr,"Warning - article %d not found\n",ap->number);           
  20906.        if (np->article_error_found) {                                           
  20907.          ap = gp->first_article;      /* restart */                             
  20908.          if (np->show_all_articles) SetArticleInTable(ap);                      
  20909.          continue;                                                              
  20910.        }                                                                        
  20911.      }                                                                          
  20912.    }                                                                            
  20913.    ap++;                                                                        
  20914.  }                                                                              
  20915.                                                                                 
  20916.  /* Now do it. */                                                               
  20917.                                                                                 
  20918.  for (ap = gp->first_article; ap <= gp->fake_last_article; ap++) {              
  20919.    if (ArticleInTable(ap)) {    /* Only articles currently in table */          
  20920.      switch (V_STATUS(gp,ap->number)) {                                         
  20921.        case V_UNREAD:         stat = "Unread"  ; break;                         
  20922.        case V_READ:           stat = "Read"    ; break;                         
  20923.        case V_MISSING_UNREAD: stat = "Missing" ; break;                         
  20924.        case V_MISSING_READ:   stat = "Missing" ; break;                         
  20925.        default:               stat = "?"       ; break;                         
  20926.      }                                                                          
  20927.      if (np->article_rows == 1) {                                               
  20928.        fprintf(xfp,"%7d %-51.51s %-8.8s %11.11s\n",                             
  20929.                    ap->number, ap->subject, stat, ap->date);                    
  20930.      }                                                                          
  20931.      else {                                                                     
  20932.        fprintf(xfp,"%7d %-51.51s %-8.8s\n",                                     
  20933.                    ap->number, ap->subject, stat);                              
  20934.      }                                                                          
  20935.      if (np->article_rows >= 2) {                                               
  20936.        fprintf(xfp,"        %-51.51s %11.11s\n", ap->from, ap->date);           
  20937.      }                                                                          
  20938.      if (np->article_rows >= 3) {                                               
  20939.        fprintf(xfp,"        %-51.51s\n", ap->message_id);                       
  20940.      }                                                                          
  20941.      if (ferror(xfp)) break;                                                    
  20942.    }                                                                            
  20943.  }                                                                              
  20944.                                                                                 
  20945.  /* Should we force the display to the top?  What do users want? */             
  20946.  np->top_article = gp->first_article;                                           
  20947.                                                                                 
  20948.  fprintf(xfp,"\n");                                                             
  20949.                                                                                 
  20950.  if (ferror(xfp)) {                                                             
  20951.    ERR2("An output error occurred writing to %s.", ep->dsname);                 
  20952.  }                                                                              
  20953.  else {                                                                         
  20954.    WARN2("A list of titles has been extracted into %s.", ep->dsname);           
  20955.  }                                                                              
  20956.                                                                                 
  20957.  if (fclose(xfp) < 0) {                                                         
  20958.    /* perror(ep->dsname); */                                                    
  20959.    ERR2("An error occurred closing data set %s.", ep->dsname);                  
  20960.  }                                                                              
  20961.                                                                                 
  20962.  return TRUE;                                                                   
  20963. }                                                                               
  20964.                                                                                 
  20965. ./   ADD NAME=NNMXARTX,SSI=01240052                                             
  20966.                                                                                 
  20967.  /********************************************************************/         
  20968.  /*                                                                  */         
  20969.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  20970.  /*                                                                  */         
  20971.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  20972.  /*                                                                  */         
  20973.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  20974.  /* including the implied warranties of merchantability and fitness, */         
  20975.  /* are expressly denied.                                            */         
  20976.  /*                                                                  */         
  20977.  /* Provided this copyright notice is included, this software may    */         
  20978.  /* be freely distributed and not offered for sale.                  */         
  20979.  /*                                                                  */         
  20980.  /* Changes or modifications may be made and used only by the maker  */         
  20981.  /* of same, and not further distributed.  Such modifications should */         
  20982.  /* be mailed to the author for consideration for addition to the    */         
  20983.  /* software and incorporation in subsequent releases.               */         
  20984.  /*                                                                  */         
  20985.  /********************************************************************/         
  20986.                                                                                 
  20987. #pragma  csect(code,  "NN@XARTX")                                               
  20988. #pragma  csect(static,"NN$XARTX")                                               
  20989. #include "nn.h"                                                                 
  20990.                                                                                 
  20991. /****** Extract article text. ****************************************/         
  20992.                                                                                 
  20993. Bool                                                                            
  20994. NNMxartx(np,gp,mode)                                                            
  20995. Rstruc nncb         *np;                                                        
  20996. Rstruc newsgroup    *gp;                                                        
  20997. enum data_set_type   mode;                                                      
  20998. {                                                                               
  20999.  Rstruc newsarticle *ap;                                                        
  21000.  FILE               *xfp;                                                       
  21001.  struct newsarticle *new_top_article = NULL;                                    
  21002.  struct extraction  *ep;                                                        
  21003.  char               *cp1;                                                       
  21004.  char               *cp2;                                                       
  21005.  struct extraction   the_extraction;                                            
  21006.  char                member  [9];                                               
  21007.  char                pdspec [32];                                               
  21008.                                                                                 
  21009.  /* Display panel asking for data set name into which to extract. */            
  21010.                                                                                 
  21011.  ep = &the_extraction;                                                          
  21012.  memset(ep,0,sizeof(struct extraction));                                        
  21013.  ep->mode = mode;                                                               
  21014.  ep->article_count = gp->real_article_count;                                    
  21015.  if (mode == PDS) strcpy(ep->panelname,"NNMPEXNP");                             
  21016.  else             strcpy(ep->panelname,"NNMPEXNS");                             
  21017.                                                                                 
  21018.  if (!((xfp=NNMgetds(np,ep)))) return TRUE;                                     
  21019.                                                                                 
  21020.  np->extract_tab_expanding          = ep->tab_expanding;                        
  21021.  np->extract_appending              = mode == PDS ? FALSE : TRUE;               
  21022.  np->extract_blank_before_separator = ep->blanking;                             
  21023.  np->extract_separator_line         = ep->separator;                            
  21024.  np->extract_write_error            = FALSE;                                    
  21025.  np->extract_close_error            = FALSE;                                    
  21026.                                                                                 
  21027.  /* for each article (subject to range option), write */                        
  21028.                                                                                 
  21029.  if ((ap=gp->first_article)) {                                                  
  21030.    for (; ap <= gp->fake_last_article; ap++) {                                  
  21031.      if (np->extract_write_error || np->extract_close_error) break;             
  21032.      if (ap->number > ep->to_article_number)                 break;             
  21033.      if (ap->number < ep->from_article_number)               continue;          
  21034.      if (!ArticleInTable(ap))                                continue;          
  21035.      if (V_LENGTH(gp) < ap->number) {                                           
  21036.        fprintf(stderr,                                                          
  21037.                "\nArticle vector error in extract_article_text\n");             
  21038.        fprintf(stderr,                                                          
  21039.         "For ap %8.8x, ap->number is %d but vector length is %d\n",             
  21040.                ap, ap->number, V_LENGTH(gp));                                   
  21041.      }                                                                          
  21042.      if (mode == PDS) {                                                         
  21043.        sprintf(member,"%8.8d",ap->number);                                      
  21044.        for (cp1=member,   cp2=ep->member_prefix;                                
  21045.            *cp1=='0' &&  *cp2;                                                  
  21046.             cp1++,        cp2++) {                                              
  21047.          *cp1 = *cp2;                                                           
  21048.        }                                                                        
  21049.        (void)NNMivput(np,"NNEXMEM ",member,-1);                                 
  21050.        sprintf(pdspec,"dd:%s(%s)",ep->ddname,member);                           
  21051.      }                                                                          
  21052.      else {                                                                     
  21053.        (void)NNMivput(np,"NNEXMEM "," ",-1);                                    
  21054.      }                                                                          
  21055.                                                                                 
  21056.      if (!new_top_article) new_top_article = ap;                                
  21057.                                                                                 
  21058.      if (!NNMpick(np,ap)) {       /* Pick article to process */                 
  21059.        fprintf(stderr,"\n*** Error accessing article %d\n",ap->number);         
  21060.        continue;                                                                
  21061.      }                                                                          
  21062.                                                                                 
  21063.      if (mode == PDS) {                                                         
  21064.        xfp = OPEN_TEXT_FILE_FOR_WRITE(pdspec);                                  
  21065.        if (!xfp) {                                                              
  21066.          perror(pdspec);                                                        
  21067.          ERR3("Cannot open member %s of PDS %s.", member, ep->dsname);          
  21068.          break;                                                                 
  21069.        }                                                                        
  21070.      }                                                                          
  21071.                                                                                 
  21072.      np->extract_file = xfp;                                                    
  21073.                                                                                 
  21074.      NNMdoit(np,ap,'E');        /* Process article picked  */                   
  21075.                                                                                 
  21076.      if (np->extract_write_error || np->extract_close_error) {                  
  21077.        /*                                                                       
  21078.         * if (mode == PDS) {                                                    
  21079.         *   if (fclose(xfp) < 0) {                                              
  21080.         *     /* perror(ep->dsname); */                                         
  21081.        /*   ERR2("An error occurred closing data set %s.", ep->dsname);         
  21082.         *     np->extract_close_error = TRUE;                                   
  21083.         *   }                                                                   
  21084.         * }                                                                     
  21085.         */                                                                      
  21086.        break;                                                                   
  21087.      }                                                                          
  21088.                                                                                 
  21089.      /* If not appending (always true for PDS),                                 
  21090.         fclose was done in NNMxtx. */                                           
  21091.                                                                                 
  21092.      if (mode == SEQ) {                                                         
  21093.        if (!ep->appending) {                                                    
  21094.          if (fclose(xfp) < 0) {                                                 
  21095.            /* perror(ep->dsname); */                                            
  21096.            ERR2("An error occurred closing data set %s.", ep->dsname);          
  21097.            np->extract_close_error = TRUE;                                      
  21098.            break;                                                               
  21099.          }                                                                      
  21100.          xfp = OPEN_TEXT_FILE_FOR_APPEND(ep->dsname);                           
  21101.          if (!xfp) {                                                            
  21102.            perror(ep->dsname);                                                  
  21103.            ERR2("Unable to open file %s.", ep->dsname);                         
  21104.            np->extract_write_error = TRUE;                                      
  21105.            break;                                                               
  21106.          }                                                                      
  21107.          ep->appending = TRUE;                                                  
  21108.        }                                                                        
  21109.      }                                                                          
  21110.    }                                                                            
  21111.  }                                                                              
  21112.                                                                                 
  21113.  if (np->extract_write_error || np->extract_close_error)                        
  21114.     np->top_article = ap;                                                       
  21115.  else if (new_top_article)                                                      
  21116.     np->top_article = new_top_article;                                          
  21117.                                                                                 
  21118.  if (xfp) {                                                                     
  21119.    if      (np->extract_write_error) {                                          
  21120.      ERR2("An error occurred writing to data set %s.", ep->dsname);             
  21121.    }                                                                            
  21122.    else if (np->extract_close_error) {                                          
  21123.      if (mode == PDS) {                                                         
  21124.      ERR3("Cannot store member %s in %s.  Check directory space.",              
  21125.           member, ep->dsname);                                                  
  21126.      }                                                                          
  21127.      else ERR2("An error occurred closing data set %s.", ep->dsname);           
  21128.    }                                                                            
  21129.    else {                                                                       
  21130.      WARN3("Articles from %s have been extracted into %s.",                     
  21131.            gp->name, ep->dsname);                                               
  21132.    }                                                                            
  21133.  }                                                                              
  21134.                                                                                 
  21135.  if (mode == PDS) {                                                             
  21136.    (void)NNMunalc(ep->ddname);                                                  
  21137.  }                                                                              
  21138.  else {                                                                         
  21139.    if (fclose(xfp) < 0) {                                                       
  21140.      /* perror(ep->dsname); */                                                  
  21141.      ERR2("An error occurred closing data set %s.", ep->dsname);                
  21142.      np->extract_close_error = TRUE;                                            
  21143.    }                                                                            
  21144.  }                                                                              
  21145.                                                                                 
  21146.  return TRUE;                                                                   
  21147. }                                                                               
  21148.                                                                                 
  21149. ./   ADD NAME=NNMXLIST,SSI=010E0026                                             
  21150.                                                                                 
  21151.  /********************************************************************/         
  21152.  /*                                                                  */         
  21153.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  21154.  /*                                                                  */         
  21155.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  21156.  /* including the implied warranties of merchantability and fitness, */         
  21157.  /* are expressly denied.                                            */         
  21158.  /*                                                                  */         
  21159.  /* Provided this copyright notice is included, this software may    */         
  21160.  /* be freely distributed and not offered for sale.                  */         
  21161.  /*                                                                  */         
  21162.  /* Changes or modifications may be made and used only by the maker  */         
  21163.  /* of same, and not further distributed.  Such modifications should */         
  21164.  /* be mailed to the author for consideration for addition to the    */         
  21165.  /* software and incorporation in subsequent releases.               */         
  21166.  /*                                                                  */         
  21167.  /********************************************************************/         
  21168.                                                                                 
  21169. #pragma  csect(code,  "NN@XLIST")                                               
  21170. #pragma  csect(static,"NN$XLIST")                                               
  21171. #include "nn.h"                                                                 
  21172.                                                                                 
  21173. /****** Extract newsgroup listing. ***********************************/         
  21174.                                                                                 
  21175. static void                                                                     
  21176. output_newsgroup_line(np,gp,xfp)                                                
  21177. Rstruc nncb         *np;                                                        
  21178. Rstruc newsgroup    *gp;                                                        
  21179. FILE                *xfp;                                                       
  21180. {                                                                               
  21181.  char                temp   [81];                                               
  21182.                                                                                 
  21183.  if (gp->fake_article_count == 0) {                                             
  21184.    strcpy(temp,"");                                                             
  21185.  }                                                                              
  21186.  else {                                                                         
  21187.    sprintf(temp,"%7d - %7d",                                                    
  21188.                 gp->fake_first_article_number,                                  
  21189.                 gp->fake_last_article_number);                                  
  21190.  }                                                                              
  21191.  fprintf(xfp,"%*.*s %*.*s %c %7d %7d %s\n",                                     
  21192.          strlen(gp->name),                                                      
  21193.          39,                                                                    
  21194.          gp->name,                                                              
  21195.          39-strlen(gp->name),                                                   
  21196.          39-strlen(gp->name),                                                   
  21197.          ".........................................",                           
  21198.          (gp->registered ? 'R' : ' '),                                          
  21199.          gp->fake_unread_count,                                                 
  21200.          gp->fake_article_count,                                                
  21201.          temp);                                                                 
  21202.                                                                                 
  21203.  return;                                                                        
  21204.                                                                                 
  21205. }                                                                               
  21206.                                                                                 
  21207. /****** Extract newsgroup listing. ***********************************/         
  21208.                                                                                 
  21209. Bool                                                                            
  21210. NNMxlist(np,rest)                                                               
  21211. Rstruc nncb         *np;                                                        
  21212. char                *rest;                                                      
  21213. {                                                                               
  21214.  Rstruc newsgroup   *gp;                                                        
  21215.  FILE               *xfp;                                                       
  21216.  struct extraction  *ep;                                                        
  21217.  char                temp   [72];                                               
  21218.  struct extraction   the_extraction;                                            
  21219.                                                                                 
  21220.  if (0 < sscanf(rest,"%s",temp)) {                                              
  21221.    ERR1("The EXTRACT command does not accept any operands.");                   
  21222.    return FALSE;                                                                
  21223.  }                                                                              
  21224.                                                                                 
  21225.  /* Display panel asking for data set name into which to extract. */            
  21226.                                                                                 
  21227.  ep = &the_extraction;                                                          
  21228.  memset(ep,0,sizeof(struct extraction));                                        
  21229.  ep->mode = SEQ;                                                                
  21230.  strcpy(ep->panelname, "NNMPEXNG");                                             
  21231.                                                                                 
  21232.  if (!((xfp=NNMgetds(np,ep)))) return TRUE;                                     
  21233.                                                                                 
  21234.  /* If append mode, and a separator line was specified, use it. */              
  21235.                                                                                 
  21236.  if (ep->appending && *ep->separator) {                                         
  21237.    fprintf(xfp,"%s\n",ep->separator);                                           
  21238.    if (ep->blanking) fprintf(xfp,"\n");                                         
  21239.  }                                                                              
  21240.                                                                                 
  21241.  fprintf(xfp,"\                                                                 
  21242.   Newsgroup Listing                          Unread   Count      \              
  21243.   Range\n\n");                                                                  
  21244.                                                                                 
  21245.  switch (np->newsgroup_order) {                                                 
  21246.    case NNTP_LIST_ORDER:                                                        
  21247.         for (gp = np->first_newsgroup_alt; gp; gp = gp->next2) {                
  21248.           if (GroupInTable(gp)) {                                               
  21249.             output_newsgroup_line(np,gp,xfp);                                   
  21250.           }                                                                     
  21251.         }                                                                       
  21252.         break;                                                                  
  21253.                                                                                 
  21254.    case NEWSRC_ORDER:        /* not implemented - fall through */               
  21255.    case ALPHABETICAL_ORDER:                                                     
  21256.    default:                  /* default is alphabetical order */                
  21257.         for (gp = np->first_newsgroup; gp; gp = gp->next) {                     
  21258.           if (GroupInTable(gp)) {                                               
  21259.             output_newsgroup_line(np,gp,xfp);                                   
  21260.           }                                                                     
  21261.         }                                                                       
  21262.         break;                                                                  
  21263.  }                                                                              
  21264.                                                                                 
  21265.  fprintf(xfp,"\n");                                                             
  21266.                                                                                 
  21267.  if (ferror(xfp)){                                                              
  21268.    ERR2("An error occurred writing to data set %s.", ep->dsname);               
  21269.  }                                                                              
  21270.  else {                                                                         
  21271.    WARN2("A list of titles has been extracted into %s.",                        
  21272.          ep->dsname);                                                           
  21273.  }                                                                              
  21274.                                                                                 
  21275.  if (fclose(xfp) < 0) {                                                         
  21276.    /* perror(ep->dsname); */                                                    
  21277.    ERR2("An error occurred closing data set %s.", ep->dsname);                  
  21278.  }                                                                              
  21279.                                                                                 
  21280.  return TRUE;                                                                   
  21281.                                                                                 
  21282. }                                                                               
  21283.                                                                                 
  21284. ./   ADD NAME=NNMXTX,SSI=01120014                                               
  21285.                                                                                 
  21286.  /********************************************************************/         
  21287.  /*                                                                  */         
  21288.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  21289.  /*                                                                  */         
  21290.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  21291.  /* including the implied warranties of merchantability and fitness, */         
  21292.  /* are expressly denied.                                            */         
  21293.  /*                                                                  */         
  21294.  /* Provided this copyright notice is included, this software may    */         
  21295.  /* be freely distributed and not offered for sale.                  */         
  21296.  /*                                                                  */         
  21297.  /* Changes or modifications may be made and used only by the maker  */         
  21298.  /* of same, and not further distributed.  Such modifications should */         
  21299.  /* be mailed to the author for consideration for addition to the    */         
  21300.  /* software and incorporation in subsequent releases.               */         
  21301.  /*                                                                  */         
  21302.  /********************************************************************/         
  21303.                                                                                 
  21304. #pragma  csect(code,  "NN@XTX  ")                                               
  21305. #pragma  csect(static,"NN$XTX  ")                                               
  21306. #include "nn.h"                                                                 
  21307.                                                                                 
  21308. /****** Extract the lines of server text into a data set. ************/         
  21309.                                                                                 
  21310. Bool                                                                            
  21311. NNMxtx(np,ap,headerstoo)                                                        
  21312. Rstruc nncb         *np;                                                        
  21313. Rstruc newsarticle  *ap;                                                        
  21314. Fool                 headerstoo;                                                
  21315. {                                                                               
  21316.  FILE               *xfp;                                                       
  21317.  struct texthdr     *thp;                                                       
  21318.  struct textline    *tp;                                                        
  21319.  struct extraction  *ep;                                                        
  21320.  int                 l;                                                         
  21321.  char               *cp;                                                        
  21322.  char                formatted_number [11];                                     
  21323.  struct extraction   the_extraction;                                            
  21324.                                                                                 
  21325.  /* If article is not specified, use main nncb, else article's text */          
  21326.                                                                                 
  21327.  thp = (ap ? &ap->thdr : &np->thdr);                                            
  21328.                                                                                 
  21329.  /* Set article data for message. */                                            
  21330.                                                                                 
  21331.  if (ap) {                                                                      
  21332.    sprintf(formatted_number,"%d",ap->number);                                   
  21333.    (void)NNMivput(np,"NNTNUM ",  formatted_number, -1);                         
  21334.    (void)NNMivput(np,"NNTSUBJ ", ap->subject,      -1);                         
  21335.  }                                                                              
  21336.                                                                                 
  21337.  if (np->extract_file) {                                                        
  21338.    if (!np->following_up) {                                                     
  21339.      (void)NNMispf(np,"CONTROL DISPLAY LOCK");                                  
  21340.      (void)NNMispf(np,"DISPLAY PANEL(NNMLEXN2)");                               
  21341.    }                                                                            
  21342.    xfp = np->extract_file;                                                      
  21343.  }                                                                              
  21344.  else {                                                                         
  21345.                                                                                 
  21346.    ep = &the_extraction;                                                        
  21347.    memset(ep,0,sizeof(struct extraction));                                      
  21348.    ep->mode = SEQ;                                                              
  21349.    strcpy(ep->panelname,"NNMPEXDS");                                            
  21350.                                                                                 
  21351.    if (!((xfp=NNMgetds(np,ep)))) return FALSE;                                  
  21352.                                                                                 
  21353.    np->extract_tab_expanding          = ep->tab_expanding;                      
  21354.    np->extract_appending              = ep->appending;                          
  21355.    np->extract_blank_before_separator = ep->blanking;                           
  21356.    np->extract_separator_line         = ep->separator;                          
  21357.  }                                                                              
  21358.                                                                                 
  21359.  /* If append mode, and a separator line was specified, use it. */              
  21360.                                                                                 
  21361.  np->extract_write_error = FALSE;                                               
  21362.  np->extract_close_error = FALSE;                                               
  21363.                                                                                 
  21364.  if (np->extract_appending) {                                                   
  21365.    if (fputc('\n',xfp) == EOF) np->extract_write_error = TRUE;                  
  21366.    else                                                                         
  21367.    if (np->extract_separator_line && *np->extract_separator_line) {             
  21368.      if (fprintf(xfp,"%s\n",np->extract_separator_line) < 0)                    
  21369.          np->extract_write_error = TRUE;                                        
  21370.      else                                                                       
  21371.      if (np->extract_blank_before_separator) {                                  
  21372.        if (fputc('\n',xfp) == EOF) np->extract_write_error = TRUE;              
  21373.      }                                                                          
  21374.    }                                                                            
  21375.  }                                                                              
  21376.                                                                                 
  21377.  if      (headerstoo)               tp = thp->first_text_line;                  
  21378.  else if ((tp=thp->text_body_line)) tp = tp->next;                              
  21379.                                                                                 
  21380.  for (;                                                                         
  21381.       tp && !np->extract_write_error;                                           
  21382.       tp = tp->next) {                                                          
  21383.    if (tp->text_length == 0) {                                                  
  21384.      if (np->following_up) fputc('>',xfp);                                      
  21385.      if (fputc('\n',xfp) == EOF) {                                              
  21386.        np->extract_write_error = TRUE; break;                                   
  21387.      }                                                                          
  21388.    }                                                                            
  21389.    else if (tp->text_length > 0) {                                              
  21390.      if (np->extract_tab_expanding) {                                           
  21391.        cp = tp->tab_expanded_text;                                              
  21392.        l  = tp->tab_expanded_text_length;                                       
  21393.      }                                                                          
  21394.      else {                                                                     
  21395.        cp = tp->text;                                                           
  21396.        l  = tp->text_length;                                                    
  21397.      }                                                                          
  21398.      for (; l > 0; cp += 251, l -= 251) {                                       
  21399.        if (np->following_up) fputc('>',xfp);                                    
  21400.        fwrite(cp,(l>251 ? 251 : l),1,xfp);                                      
  21401.        if (ferror(xfp)) {                                                       
  21402.          np->extract_write_error = TRUE; break;                                 
  21403.        }                                                                        
  21404.        if (fputc('\n',xfp) == EOF) {                                            
  21405.          np->extract_write_error = TRUE; break;                                 
  21406.        }                                                                        
  21407.      }                                                                          
  21408.    }                                                                            
  21409.  }                                                                              
  21410.                                                                                 
  21411.  if (!np->extract_write_error && ferror(xfp))                                   
  21412.     np->extract_write_error = TRUE;                                             
  21413.                                                                                 
  21414.  if (!np->following_up) {                                                       
  21415.    if (!np->extract_appending || !np->extract_file) {                           
  21416.      if (fclose(xfp) < 0) {                                                     
  21417.        /* perror(nnexdsn); */                                                   
  21418.        ERR2("An error occurred closing data set %s.", ep->dsname);              
  21419.        np->extract_close_error = TRUE;                                          
  21420.        return FALSE;                                                            
  21421.      }                                                                          
  21422.    }                                                                            
  21423.  }                                                                              
  21424.  if (!np->extract_file) {                                                       
  21425.    if (np->extract_write_error) {                                               
  21426.      ERR2("An error occurred writing to data set %s.", ep->dsname);             
  21427.      np->extract_write_error = TRUE;                                            
  21428.    }                                                                            
  21429.    else if (ap) {                                                               
  21430.      WARN3("Article %d extracted into file %s.",                                
  21431.             ap->number, ep->dsname);                                            
  21432.    }                                                                            
  21433.    else {                                                                       
  21434.      WARN2("Displayed text has been extracted into file %s.",                   
  21435.             ep->dsname);                                                        
  21436.    }                                                                            
  21437.  }                                                                              
  21438.  if (np->extract_write_error) return FALSE;                                     
  21439.  else return TRUE;                                                              
  21440. }                                                                               
  21441.                                                                                 
  21442. ./ ENDUP                                                                        
  21443. ?!                                                                              
  21444. //CLIST    EXEC NNLOAD,TRK1='4',TO='CLIST'                                      
  21445. //SYSIN    DD DATA,DLM='?!'                                                     
  21446. ./   ADD NAME=NNMFIUCV,SSI=01010036                                             
  21447. /* REXX.  This exec scans the job pack queues for IUCVMULT and returns          
  21448.  * with an error code if IUCVMULT is already loaded under a                     
  21449.  * different TCB. This can only happen under PIE MultiTSO or a                  
  21450.  * similar product that makes multiple job step TCB's.                          
  21451.  */                                                                             
  21452.                                                                                 
  21453. trace off                                                                       
  21454. signal on novalue                                                               
  21455.                                                                                 
  21456. search_name = "IUCVMULT"                                                        
  21457. count = 0                                                                       
  21458. foundtcb. = ""                                                                  
  21459. current_tcb  = getword24("21C")                                                 
  21460. current_job_step_tcb = getword24(current_tcb,"7C")                              
  21461. current_ascb = getword24("224")                                                 
  21462. current_asxb = getword31(current_ascb,"6C")                                     
  21463. first_tcb    = getword24(current_asxb,"4")                                      
  21464. tcb = first_tcb                                                                 
  21465. motherflag = 0                                                                  
  21466. do forever                                                                      
  21467.  if motherflag = 0 then do                                                      
  21468.   call process                                                                  
  21469.   daughter_tcb = getword24(tcb,"88")                                            
  21470.   if daughter_tcb \= "00000000" then do                                         
  21471.    tcb = daughter_tcb                                                           
  21472.    iterate                                                                      
  21473.   end                                                                           
  21474.  end                                                                            
  21475.  motherflag = 0                                                                 
  21476.  sister_tcb = getword24(tcb, "80")                                              
  21477.  if sister_tcb \= "00000000" then do                                            
  21478.   tcb = sister_tcb                                                              
  21479.   iterate                                                                       
  21480.  end                                                                            
  21481.  mother_tcb = getword24(tcb, "84")                                              
  21482.  if mother_tcb \= "00000000" then do                                            
  21483.   tcb = mother_tcb                                                              
  21484.   motherflag = 1                                                                
  21485.   iterate                                                                       
  21486.  end                                                                            
  21487.  leave                                                                          
  21488. end                                                                             
  21489.                                                                                 
  21490. if count = 0 then return 0                                                      
  21491. problem = 0                                                                     
  21492. do i = 1 to count                                                               
  21493.  if foundtcb.i = current_job_step_tcb then do                                   
  21494.   /*                                                                            
  21495.   say search_name "is already loaded under current TCB at "foundtcb.i"."        
  21496.   */                                                                            
  21497.  end                                                                            
  21498.  else do                                                                        
  21499.   /*                                                                            
  21500.   say search_name "is loaded under different TCB at "foundtcb.i"."              
  21501.   */                                                                            
  21502.   problem = 1                                                                   
  21503.  end                                                                            
  21504. end                                                                             
  21505.                                                                                 
  21506. if problem = 1 then return 1                                                    
  21507.                                                                                 
  21508. else return 0                                                                   
  21509.                                                                                 
  21510. process:                                                                        
  21511.                                                                                 
  21512.  jpq = getword31(tcb,"2C")                                                      
  21513.  cde = jpq                                                                      
  21514.  do while cde \= "00000000"                                                     
  21515.   cde_contents = storage(cde,32)                                                
  21516.   cde_name = substr(cde_contents,9,8)                                           
  21517.   cde_epa  = substr(cde_contents,9,8)                                           
  21518.   if search_name = cde_name then do                                             
  21519.    count = count + 1                                                            
  21520.    foundtcb.count = tcb                                                         
  21521.   end                                                                           
  21522.   cde = getword31(cde,"0")                                                      
  21523.  end                                                                            
  21524.                                                                                 
  21525. return                                                                          
  21526.                                                                                 
  21527. getword31: parse arg addr, offset                                               
  21528. temp1 = x2d(addr)                                                               
  21529. if offset = "" then temp2 = 0                                                   
  21530. else temp2 = x2d(offset)                                                        
  21531. return c2x(storage(d2x(temp1+temp2),4))                                         
  21532.                                                                                 
  21533. getword24: parse arg addr, offset                                               
  21534. temp1 = x2d(addr)                                                               
  21535. if offset = "" then temp2 = 0                                                   
  21536. else temp2 = x2d(offset)                                                        
  21537. return "00"c2x(storage(d2x(temp1+temp2+1),3))                                   
  21538.                                                                                 
  21539. ./   ADD NAME=NNMMAIL,SSI=01030000                                              
  21540. /* REXX */                                                                      
  21541.                                                                                 
  21542. /*********************************************************************/         
  21543. /*                                                                   */         
  21544. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     */         
  21545. /*                                                                   */         
  21546. /* This software is provided on an "AS IS" basis.  All warranties,   */         
  21547. /* including the implied warranties of merchantability and fitness,  */         
  21548. /* are expressly denied.                                             */         
  21549. /*                                                                   */         
  21550. /* Provided this copyright notice is included, this software may     */         
  21551. /* be freely distributed and not offered for sale.                   */         
  21552. /*                                                                   */         
  21553. /* Changes or modifications may be made and used only by the maker   */         
  21554. /* of same, and not further distributed.  Such modifications should  */         
  21555. /* be mailed to the author for consideration for addition to the     */         
  21556. /* software and incorporation in subsequent releases.                */         
  21557. /*                                                                   */         
  21558. /*********************************************************************/         
  21559.                                                                                 
  21560. /**********************************************************************/        
  21561. /*                                                                    */        
  21562. /* Argument 1: mail data set                                          */        
  21563. /* Argument 2: recipient(s)                                           */        
  21564. /*                                                                    */        
  21565. /**********************************************************************/        
  21566.                                                                                 
  21567. trace off                                                                       
  21568. address TSO                                                                     
  21569.                                                                                 
  21570. /* Tailor these to your installation requirements. */                           
  21571.                                                                                 
  21572. local_userid    = userid()                                                      
  21573. local_domain    = "MVS"                                                         
  21574. local_origin    = "mvs.draper.com"                                              
  21575. local_smtp_node = "SMTPSRV"                                                     
  21576.                                                                                 
  21577. parse arg maildsn to                                                            
  21578.                                                                                 
  21579. if pos("@",to) = 0 then to = to"@"local_origin                                  
  21580. else do                                                                         
  21581.  parse var to before "<" after ">" junk                                         
  21582.  if after <> "" then to = after                                                 
  21583. end                                                                             
  21584.                                                                                 
  21585. "ALLOC FI(NNMMAILI) SHR REU DA("maildsn")"                                      
  21586. if rc \= 0 then return rc                                                       
  21587. "EXECIO * DISKR NNMMAILI (FINIS STEM IN.)"                                      
  21588. if rc \= 0 then return rc                                                       
  21589. "newstack"                                                                      
  21590. say   "HELO" local_domain                                                       
  21591. queue "HELO" local_domain                                                       
  21592. say   "MAIL FROM:<"local_userid"@"local_origin">"                               
  21593. queue "MAIL FROM:<"local_userid"@"local_origin">"                               
  21594. say   "RCPT TO:<"to">"                                                          
  21595. queue "RCPT TO:<"to">"                                                          
  21596. queue "DATA"                                                                    
  21597. do i = 1 to in.0                                                                
  21598.  if left(in.i,1) = "." then queue "."in.i                                       
  21599.  else if in.i = "" then queue " "                                               
  21600.  else queue in.i                                                                
  21601. end                                                                             
  21602. queue "."                                                                       
  21603. queue "QUIT"                                                                    
  21604. queue ""                                                                        
  21605. "EXECIO * DISKW NNMMAILI (FINIS)"                                               
  21606. if rc \= 0 then return rc                                                       
  21607. "delstack"                                                                      
  21608. "FREE FI(NNMMAILI)"                                                             
  21609.                                                                                 
  21610. "TRANSMIT" local_domain"."local_smtp_node,                                      
  21611.            "DATASET("maildsn") NOEPILOG NOLOG NOPROLOG"                         
  21612.                                                                                 
  21613. return 0                                                                        
  21614.                                                                                 
  21615. /* The following function enquotes a string. */                                 
  21616. quote:                                                                          
  21617. parse arg string                                                                
  21618. ix = 1                                                                          
  21619. do forever                                                                      
  21620.  ix = pos("'",string,ix)                                                        
  21621.  if ix = 0 then return "'"string"'"                                             
  21622.  string = insert("'",string,ix)                                                 
  21623.  ix=ix+2                                                                        
  21624. end                                                                             
  21625. ./   ADD NAME=NNMVS,SSI=010D0000                                                
  21626. /* REXX. Syntax:  NNMVS  (we'll do the rest)   */                               
  21627.                                                                                 
  21628. /*********************************************************************/         
  21629. /*                                                                   */         
  21630. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     */         
  21631. /*                                                                   */         
  21632. /* This software is provided on an "AS IS" basis.  All warranties,   */         
  21633. /* including the implied warranties of merchantability and fitness,  */         
  21634. /* are expressly denied.                                             */         
  21635. /*                                                                   */         
  21636. /* Provided this copyright notice is included, this software may     */         
  21637. /* be freely distributed and not offered for sale.                   */         
  21638. /*                                                                   */         
  21639. /* Changes or modifications may be made and used only by the maker   */         
  21640. /* of same, and not further distributed.  Such modifications should  */         
  21641. /* be mailed to the author for consideration for addition to the     */         
  21642. /* software and incorporation in subsequent releases.                */         
  21643. /*                                                                   */         
  21644. /*********************************************************************/         
  21645.                                                                                 
  21646. /* *** Customize the following lines for your installation. *** */              
  21647. /*                                                              */              
  21648. /* Note:  If you wish to specify a different ISPF APPLID for    */              
  21649. /* NNMVS, you will have to use the SELECT service to invoke     */              
  21650. /* the load module.  If so, uncomment the LIBDEF's for ISPLLIB  */              
  21651. /* and the SELECT call, and comment out the TSO CALL call.      */              
  21652. /*                                                              */              
  21653. /* Note:  If you choose a panel library that is in TSO users'   */              
  21654. /* default ISPF allocations, you can remove the LIBDEF call.    */              
  21655. /*                                                              */              
  21656.                                                                                 
  21657. nnmprefix      = "NNMVS"                                                        
  21658. nnmpanelsuffix = "ISPPLIB"                                                      
  21659. nnmloadsuffix  = "LOAD"                                                         
  21660. nnmlmod        = "NNMMAIN"                                                      
  21661. nnmpanel       = nnmprefix"."nnmpanelsuffix                                     
  21662. nnmload        = nnmprefix"."nnmloadsuffix                                      
  21663. nnmappl        = "ISR"                                                          
  21664.                                                                                 
  21665. trace off                                                                       
  21666. signal on novalue                                                               
  21667. libdeffed = 0                                                                   
  21668. parse arg args                                                                  
  21669. "ISPQRY"                                                                        
  21670. if rc > 0 then do                                                               
  21671.  parse source . . execname . execds .                                           
  21672.  if execds = "?" then                                                           
  21673.   icmd = "%"execname args                                                       
  21674.  else                                                                           
  21675.   icmd = "EX '"execds"("execname")'" quote(args)                                
  21676.  call startispf "NEWAPPL("nnmappl") CMD("icmd")"                                
  21677.  exit                                                                           
  21678. end                                                                             
  21679. signal on failure                                                               
  21680. signal on halt                                                                  
  21681. testparm = "-"                                                                  
  21682. if wordpos("TEST", translate(args)) > 0 then testparm = testparm || "t"         
  21683. else ,                                                                          
  21684. if wordpos("DEBUG",translate(args)) > 0 then testparm = testparm || "d"         
  21685. else testparm = ""                                                              
  21686.                                                                                 
  21687. if find_iucvmult() <> 0 then do                                                 
  21688.  say,                                                                           
  21689. "A TCP/IP socket application may be active elsewhere in your session."          
  21690.  say "Please terminate the other application before trying this one."           
  21691.  exit                                                                           
  21692. end                                                                             
  21693.                                                                                 
  21694. call libdef                                                                     
  21695. call nnm_dialog                                                                 
  21696.                                                                                 
  21697. cleanup:                                                                        
  21698. if libdeffed then call unlibdef                                                 
  21699. exit                                                                            
  21700. error:failure:halt:say "NNMVS: Severe lossage."                                 
  21701. say "Statement:" sourceline(sigl)                                               
  21702. exit                                                                            
  21703.                                                                                 
  21704. nnm_dialog:                                                                     
  21705.                                                                                 
  21706. address TSO "CALL" "'"nnmload"("nnmlmod")'" quote(testparm)                     
  21707. /*                                                                              
  21708.  * address ISPEXEC,                                                             
  21709.  *         "SELECT PGM("nnmlmod") PARM("quote(testparm)")",                     
  21710.  *         "NEWAPPL("nnmappl") PASSLIB"                                         
  21711.  */                                                                             
  21712. if rc \= 0 then say "Return code from" nnmlmod "program is" rc                  
  21713. return                                                                          
  21714.                                                                                 
  21715. libdef:                                                                         
  21716. address ISPEXEC "LIBDEF ISPPLIB DATASET  ID('"nnmpanel"')"                      
  21717. /*                                                                              
  21718.  * address ISPEXEC "LIBDEF ISPLLIB DATASET  ID('"nnmload"')"                    
  21719.  */                                                                             
  21720. libdeffed = 1                                                                   
  21721. return                                                                          
  21722.                                                                                 
  21723. unlibdef:                                                                       
  21724. /*                                                                              
  21725.  * address ISPEXEC "LIBDEF ISPLLIB DATASET"                                     
  21726.  */                                                                             
  21727. address ISPEXEC "LIBDEF ISPPLIB DATASET"                                        
  21728. libdeffed = 0                                                                   
  21729. return                                                                          
  21730.                                                                                 
  21731. /*                                                                              
  21732.  * The following function starts ISPF from READY mode.                          
  21733.  * Beware:  splitting the screen starts up an identical copy of the             
  21734.  *          application, which may not be desirable.                            
  21735.  */                                                                             
  21736.                                                                                 
  21737. startispf: parse arg string                                                     
  21738. "ISPSTART" string                                                               
  21739. return                                                                          
  21740.                                                                                 
  21741. /* The following function enquotes a string. */                                 
  21742.                                                                                 
  21743. quote: parse arg string                                                         
  21744. ix = 1                                                                          
  21745. do forever                                                                      
  21746.  ix = pos("'",string,ix)                                                        
  21747.  if ix = 0 then return "'"string"'"                                             
  21748.  string = insert("'",string,ix)                                                 
  21749.  ix=ix+2                                                                        
  21750. end                                                                             
  21751.                                                                                 
  21752. find_iucvmult: procedure                                                        
  21753.                                                                                 
  21754. call nnmfiucv                                                                   
  21755.                                                                                 
  21756. return result                                                                   
  21757.                                                                                 
  21758. ./   ADD NAME=NNMVSC,SSI=01030012                                               
  21759. PROC 0 TEST DEBUG BATCH +                                                       
  21760.        SERVER() GROUP() NEWSRC() OPTION() REGISTERSTATUS()                      
  21761.                                                                                 
  21762. /*********************************************************************/         
  21763. /*                                                                   */         
  21764. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     */         
  21765. /*                                                                   */         
  21766. /* This software is provided on an "AS IS" basis.  All warranties,   */         
  21767. /* including the implied warranties of merchantability and fitness,  */         
  21768. /* are expressly denied.                                             */         
  21769. /*                                                                   */         
  21770. /* Provided this copyright notice is included, this software may     */         
  21771. /* be freely distributed and not offered for sale.                   */         
  21772. /*                                                                   */         
  21773. /* Changes or modifications may be made and used only by the maker   */         
  21774. /* of same, and not further distributed.  Such modifications should  */         
  21775. /* be mailed to the author for consideration for addition to the     */         
  21776. /* software and incorporation in subsequent releases.                */         
  21777. /*                                                                   */         
  21778. /*********************************************************************/         
  21779.                                                                                 
  21780. /**********************************************************************/        
  21781. /*                                                                    */        
  21782. /* This is the CLIST version of the NNMVS driver.  You may wish to    */        
  21783. /* use this in place of the REXX version if:                          */        
  21784. /*                                                                    */        
  21785. /* - you don't have REXX (huh???)                                     */        
  21786. /* - you don't have XPROC (you can probably get it from the same      */        
  21787. /*   place you got NNMVS)                                             */        
  21788. /* - you are experiencing RACF/ACF2/other-security-system problems    */        
  21789. /*   trying to define access to the NNTP authorization file with      */        
  21790. /*   program pathing rules or the equivalent                          */        
  21791. /*                                                                    */        
  21792. /* The disadvantages are:                                             */        
  21793. /*                                                                    */        
  21794. /* - You can use the CLIST from READY mode only implicitly.  In other */        
  21795. /*   words, a user won't be able to type EXEC 'library.clist(NNMVS)'  */        
  21796. /*   from READY mode - it must be in SYSPROC and executed by name.    */        
  21797. /*                                                                    */        
  21798. /* - You don't get the check for multiple TCP/IP applications.        */        
  21799. /*                                                                    */        
  21800. /* Of course, even if you don't have XPROC, you may still want to use */        
  21801. /* the REXX exec instead - you just have to take out the XPROC call   */        
  21802. /* and forget about being able to pass parameters to the exec.  That  */        
  21803. /* isn't such a great loss, since none of the params are required.    */        
  21804. /*                                                                    */        
  21805. /**********************************************************************/        
  21806.                                                                                 
  21807. /* *** Customize the following lines for your installation. *** */              
  21808. /*                                                              */              
  21809. /* Note:  If you wish to specify a different ISPF APPLID for    */              
  21810. /* NNMVS, you will have to use the SELECT service to invoke     */              
  21811. /* the load module.  If so, uncomment the LIBDEF's for ISPLLIB  */              
  21812. /* and the SELECT call, and comment out the TSO CALL call.      */              
  21813. /*                                                              */              
  21814. /* Note:  If you choose a panel library that is in TSO users'   */              
  21815. /* default ISPF allocations, you can remove the LIBDEF call.    */              
  21816. /*                                                              */              
  21817.                                                                                 
  21818. SET NNMCLIST       = NNMVS     /* name of this CLIST */                         
  21819. SET NNMPREFIX      = NNMVS                                                      
  21820. SET NNMPANELSUFFIX = ISPPLIB                                                    
  21821. SET NNMLOADSUFFIX  = LOAD                                                       
  21822. SET NNMLMOD        = NNMMAIN                                                    
  21823. SET NNMPANEL       = &STR(&NNMPREFIX..&NNMPANELSUFFIX)                          
  21824. SET NNMLOAD        = &STR(&NNMPREFIX..&NNMLOADSUFFIX)                           
  21825. SET NNMAPPL        = ISR                                                        
  21826.                                                                                 
  21827. CONTROL NOCAPS                                                                  
  21828.                                                                                 
  21829. SET STACKED = N                                                                 
  21830. SET LIBDEFFED = N                                                               
  21831. ISPQRY                                                                          
  21832. IF &LASTCC > 0 THEN DO                                                          
  21833.  SET ICMD = &NRSTR(&NNMCLIST &TEST &DEBUG &BATCH +                              
  21834.                    SERVER('&SERVER') GROUP('&GROUP') +                          
  21835.                    NEWSRC('&NEWSRC') OPTION('&OPTION') +                        
  21836.                    REGISTERSTATUS('®ISTERSTATUS'))                           
  21837.  ISPSTART NEWAPPL(&NNMAPPL) CMD(&NRSTR(&ICMD))                                  
  21838.  EXIT                                                                           
  21839. END                                                                             
  21840.                                                                                 
  21841. IF &NRSTR(&OPTION) ^= &STR() THEN DO                                            
  21842.  IF &LENGTH(&NRSTR(&OPTION)) ^= 1 +                                             
  21843.   | &SYSINDEX(&NRSTR(&OPTION),TDB) ^= 0 THEN DO                                 
  21844.   WRITE NNMVS: Invalid option, &NRSTR(&OPTION).                                 
  21845.   EXIT CODE(12)                                                                 
  21846.  END                                                                            
  21847.  IF &NRSTR(&SERVER) = &STR() THEN DO                                            
  21848.   WRITE NNMVS: SERVER required when OPTION specified.                           
  21849.   EXIT CODE(12)                                                                 
  21850.  END                                                                            
  21851.  IF &NRSTR(&NEWSRC) = &STR() THEN DO                                            
  21852.   WRITE NNMVS: NEWSRC required when OPTION specified.                           
  21853.   EXIT CODE(12)                                                                 
  21854.  END                                                                            
  21855.  IF &NRSTR(&OPTION) = G && &NRSTR(&GROUP) = &STR() THEN DO                      
  21856.   WRITE NNMVS: GROUP required when OPTION(G) specified.                         
  21857.   EXIT CODE(12)                                                                 
  21858.  END                                                                            
  21859.  IF &NRSTR(REGISTERSTATUS) = &STR() THEN SET REGISTERSTATUS = PROMPT            
  21860. END                                                                             
  21861.                                                                                 
  21862. SET TESTPARM = &STR(-)                                                          
  21863. IF &TEST  = TEST  THEN SET TESTPARM = &STR(&TESTPARM.t)                         
  21864. IF &DEBUG = DEBUG THEN SET TESTPARM = &STR(&TESTPARM.d)                         
  21865. IF &BATCH = BATCH THEN SET TESTPARM = &STR(&TESTPARM.b)                         
  21866.                                                                                 
  21867. ISPEXEC LIBDEF ISPPLIB DATASET ID('&NNMPANEL')                                  
  21868.                                                                                 
  21869. /* ISPEXEC LIBDEF ISPLLIB DATASET ID('&NNMLOAD')                                
  21870.                                                                                 
  21871. SET LIBDEFFED = Y                                                               
  21872.                                                                                 
  21873. IF &NRSTR(&SERVER) NE THEN DO                                                   
  21874.  SET NNSERVER = &NRSTR(&SERVER)                                                 
  21875.  ISPEXEC VPUT (NNSERVER)                                                        
  21876. END                                                                             
  21877.                                                                                 
  21878. IF &NRSTR(&GROUP) NE THEN DO                                                    
  21879.  SET NNGROUPI = &NRSTR(&GROUP)                                                  
  21880.  ISPEXEC VPUT (NNGROUPI)                                                        
  21881. END                                                                             
  21882.                                                                                 
  21883. IF &NRSTR(&NEWSRC) NE THEN DO                                                   
  21884.  SET NNNEWSRF = &NRSTR(&NEWSRC)                                                 
  21885.  ISPEXEC VPUT (NNNEWSRF)                                                        
  21886. END                                                                             
  21887.                                                                                 
  21888. SET VPUTVARS =                                                                  
  21889.                                                                                 
  21890. IF &NRSTR(&SERVER) ^= &STR() THEN DO                                            
  21891.  SET NNSERVER = &NRSTR(&SERVER)                                                 
  21892.  SET VPUTVARS = &STR(&VPUTVARS NNSERVER)                                        
  21893. END                                                                             
  21894.                                                                                 
  21895. IF &NRSTR(&GROUP) ^= &STR() | &NRSTR(&OPTION) = G THEN DO                       
  21896.  SET NNGROUPI = &NRSTR(&GROUP)                                                  
  21897.  SET VPUTVARS = &STR(&VPUTVARS NNGROUPI)                                        
  21898. END                                                                             
  21899.                                                                                 
  21900. IF &NRSTR(&NEWSRC) ^= &STR() THEN DO                                            
  21901.  SET NNNEWSRF = &NRSTR(&NEWSRC)                                                 
  21902.  SET L = &LENGTH(&NRSTR(&NEWSRC))                                               
  21903.  IF   &SUBSTR(1,&NEWSRC) = &STR(') +                                            
  21904.    && &SUBSTR(&L,&NEWSRC) = &STR(') THEN DO                                     
  21905.   SET NNNEWSRC = &SUBSTR(2:&L-1,&NRSTR(&NEWSRC))                                
  21906.  END                                                                            
  21907.  ELSE SET NNNEWSRC = &NRSTR(&SYSPREF..&NEWSRC)                                  
  21908.  SET VPUTVARS = &STR(&VPUTVARS NNNEWSRF NNNEWSRC)                               
  21909. END                                                                             
  21910.                                                                                 
  21911. IF &NRSTR(®ISTERSTATUS) ^= &STR() THEN DO                                    
  21912.  SET NNREGNNG = &SUBSTR(1,&NRSTR(®ISTERSTATUS)                               
  21913.  SET VPUTVARS = &STR(&VPUTVARS NNREGNNG)                                        
  21914. END                                                                             
  21915.                                                                                 
  21916. IF &STR(VPUTVARS) ^= &STR() THEN DO                                             
  21917.  ISPEXEC VPUT (VPUTVARS) PROFILE                                                
  21918. END                                                                             
  21919.                                                                                 
  21920. IF &NRSTR(&OPTION) ^= &STR() THEN DO                                            
  21921.  SET TESTPARM = &NRSTR(&TESTPARM.&OPTION)                                       
  21922. END                                                                             
  21923.                                                                                 
  21924. CALL '&NNMLOAD(&NNMLMOD)' '&NRSTR(&TESTPARM)'                                   
  21925. /*                                                                              
  21926. /* address ISPEXEC,                                                             
  21927. /* ISPEXEC SELECT PGM(&NNMLMOD) PARM('&NRSTR(&TESTPARM)') +                     
  21928. /*         NEWAPPL(&NNMAPPL) PASSLIB                                            
  21929. /*                                                                              
  21930. IF &LASTCC NE 0 THEN DO                                                         
  21931.  WRITE Return code from &NNMLMOD program is &LASTCC                             
  21932. END                                                                             
  21933.                                                                                 
  21934. IF &LIBDEFFED = Y THEN DO                                                       
  21935.                                                                                 
  21936.  /* ISPEXEC LIBDEF ISPLLIB DATASET                                              
  21937.                                                                                 
  21938.  ISPEXEC LIBDEF ISPPLIB DATASET                                                 
  21939.  SET LIBDEFFED = N                                                              
  21940. END                                                                             
  21941.                                                                                 
  21942. EXIT                                                                            
  21943.                                                                                 
  21944. ./   ADD NAME=NNMVSL,SSI=01030003                                               
  21945. /* REXX.  From Leonard D. Woren <ldw@mvsa.usc.edu>.                             
  21946.  *        Modified by SEB to remove MSGS file and other stuff...                
  21947.  *                                                                              
  21948.  */                                                                             
  21949. trace off                                                                       
  21950. signal on failure                                                               
  21951. signal on novalue                                                               
  21952.                                                                                 
  21953. "XPROC 0 DEBUG LIST NEW OLD"                                                    
  21954. if rc <> 0 then return rc                                                       
  21955.                                                                                 
  21956. If debug = 'DEBUG' Then Trace I                                                 
  21957. If list  = 'LIST'  Then Trace C                                                 
  21958. Address ISPEXEC                                                                 
  21959.                                                                                 
  21960. nnmvs_command = "%NNMVSP" new old                                               
  21961. panel_name    = "NNL"                                                           
  21962. prof = "ISPPROF"                                                                
  21963. Address TSO "PIECHECK"                                                          
  21964. piecc = Rc                                                                      
  21965. Select                                                                          
  21966.    When(piecc =   0) Then Nop   /* not under pie */                             
  21967.    When(piecc =  12) Then Nop   /* no piecheck cmd ==> not under pie */         
  21968.    When(piecc = 241) Then Nop   /* pie session 1 */                             
  21969.    Otherwise         prof = 'IS1PROF'                                           
  21970.    End  /* select */                                                            
  21971.                                                                                 
  21972. "CONTROL ERRORS RETURN"                                                         
  21973. "TBOPEN NNLIST WRITE LIBRARY("prof") SHARE"                                     
  21974. If Rc > 8 then signal ispf_error                                                
  21975. If Rc = 0 Then "TBTOP NNLIST"                                                   
  21976. Else Do                                                                         
  21977.    "TBCREATE NNLIST WRITE LIBRARY("prof") NAMES(SERVER NEWSRC)"                 
  21978.    If Rc ^= 0 Then signal ispf_error                                            
  21979.    End                                                                          
  21980. csr = ""                                                                        
  21981. dispcc = 0                                                                      
  21982.                                                                                 
  21983.                                                                                 
  21984. Do Forever                                                                      
  21985.    "TBQUERY NNLIST ROWNUM(ROWNUM)"                                              
  21986.    If Rc > 8 then signal ispf_error                                             
  21987.    If rownum = 0 Then Do                                                        
  21988.       server = ""                                                               
  21989.       newsrc = ""                                                               
  21990.       "TBADD NNLIST"                                                            
  21991.       If RC > 8 then signal ispf_error                                          
  21992.       csr = "CURSOR(SERVER) CSRROW(1)"                                          
  21993.       End                                                                       
  21994.                                                                                 
  21995.    "TBTOP   NNLIST"                                                             
  21996.    If Rc > 8 then signal ispf_error                                             
  21997.    nnsel = ""                                                                   
  21998.    If dispcc = 4 Then "TBDISPL NNLIST"                                          
  21999.                  Else "TBDISPL NNLIST PANEL("panel_name")" csr                  
  22000.    dispcc = Rc                                                                  
  22001.    csr = ""                                                                     
  22002.                                                                                 
  22003.    If dispcc = 8 Then Do                                                        
  22004.       "TBCLOSE NNLIST PAD(50) LIBRARY("prof")"                                  
  22005.       If Rc > 8 then signal ispf_error                                          
  22006.       return 0                                                                  
  22007.       End                                                                       
  22008.                                                                                 
  22009.    If (dispcc ^= 0 & dispcc ^= 4) Then Do                                       
  22010.       Say "TBDISPL Rc =" dispcc                                                 
  22011.       Say zerrsm                                                                
  22012.       Say zerrlm                                                                
  22013.       "TBCLOSE NNLIST PAD(50) LIBRARY("prof")"                                  
  22014.       If Rc > 8 then signal ispf_error                                          
  22015.       return 16                                                                 
  22016.       End                                                                       
  22017.                                                                                 
  22018.    If zcmd = "" Then Do  /* look for line commands */                           
  22019.       Upper nnsel                                                               
  22020.       Select                                                                    
  22021.          When (nnsel = "" ) Then "TBPUT NNLIST"                                 
  22022.          When (nnsel = "D") Then Do                                             
  22023.             /*                                                                  
  22024.             "CONTROL DISPLAY SAVE"                                              
  22025.             "DISPLAY PANEL(NNLDEL)"                                             
  22026.             delcc = Rc                                                          
  22027.             "CONTROL DISPLAY RESTORE"                                           
  22028.             if delcc > 8 then signal ispf_error                                 
  22029.             If delcc = 0 Then */ "TBDELETE NNLIST"                              
  22030.             Iterate                                                             
  22031.             End                                                                 
  22032.          When (nnsel = "I") Then Do                                             
  22033.             server = ""                                                         
  22034.             newsrc = ""                                                         
  22035.             "TBADD NNLIST"                                                      
  22036.             if Rc > 8 then signal ispf_error                                    
  22037.             "TBQUERY NNLIST POSITION(NEWROW)"                                   
  22038.             if Rc > 8 then signal ispf_error                                    
  22039.             csr = "CURSOR(SERVER) CSRROW("newrow")"                             
  22040.             Iterate                                                             
  22041.             End                                                                 
  22042.          When (nnsel = "R") Then Do                                             
  22043.             "TBADD NNLIST"                                                      
  22044.             if Rc > 8 then signal ispf_error                                    
  22045.             "TBQUERY NNLIST POSITION(NEWROW)"                                   
  22046.             if Rc > 8 then signal ispf_error                                    
  22047.             csr = "CURSOR(SERVER) CSRROW("newrow")"                             
  22048.             Iterate                                                             
  22049.             End                                                                 
  22050.          When (nnsel = "S") Then Do                                             
  22051.             "TBCLOSE NNLIST PAD(50) LIBRARY("prof")"                            
  22052.             cc = Rc                                                             
  22053.             if cc > 8 then signal ispf_error                                    
  22054.             If cc ^= 0 Then Say "TBCLOSE rc =" cc                               
  22055.             operands = ""                                                       
  22056.             If server ^= "" Then operands =          "SERVER("server")"         
  22057.             If newsrc ^= "" Then operands = operands "NEWSRC("newsrc")"         
  22058.             Address TSO nnmvs_command operands                                  
  22059.             return 0                                                            
  22060.             End                                                                 
  22061.          Otherwise Do                                                           
  22062.             badsel = nnsel                                                      
  22063.             zerrsm   = badsel "invalid"                                         
  22064.             zerrlm   = badsel "is not a valid line command"                     
  22065.             zerralrm = "YES"                                                    
  22066.             zerrhm   = "*"                                                      
  22067.             "SETMSG MSG(ISRZ002)"                                               
  22068.             If Rc > 8 Then signal ispf_error                                    
  22069.             End                                                                 
  22070.          End /* select */                                                       
  22071.       End  /* zcmd = "" */                                                      
  22072. Else Do  /* zcmd ^= "" */                                                       
  22073.       badcmd = Word(zcmd,1)                                                     
  22074.       zerrsm   = "Invalid command"                                              
  22075.       zerrlm   = badcmd "is not a valid primary command"                        
  22076.       zerralrm = "YES"                                                          
  22077.       zerrhm   = "*"                                                            
  22078.       "SETMSG MSG(ISRZ002)"                                                     
  22079.       If Rc > 8 Then signal ispf_error                                          
  22080.       End  /* zcmd ^= "" */                                                     
  22081.    End  /* main loop */                                                         
  22082.                                                                                 
  22083. return 0                                                                        
  22084.                                                                                 
  22085. /* ISPF dialog error handling. */                                               
  22086.                                                                                 
  22087. ispf_error:                                                                     
  22088. address ISPEXEC "DISPLAY PANEL(ISPTERM)"                                        
  22089. signal cleanup                                                                  
  22090.                                                                                 
  22091. error:failure:halt:say "NNMVSL: Severe lossage."                                
  22092. say "Statement:" sourceline(sigl)                                               
  22093. exit                                                                            
  22094. ./   ADD NAME=NNMVSP,SSI=010D0033                                               
  22095. /* REXX. Syntax:  NNMVS  (see XPROC for the rest)   */                          
  22096.                                                                                 
  22097. /*********************************************************************/         
  22098. /*                                                                   */         
  22099. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     */         
  22100. /*                                                                   */         
  22101. /* This software is provided on an "AS IS" basis.  All warranties,   */         
  22102. /* including the implied warranties of merchantability and fitness,  */         
  22103. /* are expressly denied.                                             */         
  22104. /*                                                                   */         
  22105. /* Provided this copyright notice is included, this software may     */         
  22106. /* be freely distributed and not offered for sale.                   */         
  22107. /*                                                                   */         
  22108. /* Changes or modifications may be made and used only by the maker   */         
  22109. /* of same, and not further distributed.  Such modifications should  */         
  22110. /* be mailed to the author for consideration for addition to the     */         
  22111. /* software and incorporation in subsequent releases.                */         
  22112. /*                                                                   */         
  22113. /*********************************************************************/         
  22114.                                                                                 
  22115. /* *** Customize the following lines for your installation. *** */              
  22116. /*                                                              */              
  22117. /* If nnmpanel is set to "", it will not be LIBDEF'd.           */              
  22118. /* If nnmload  is set to "", it will not be LIBDEF'd.           */              
  22119. /*                                                              */              
  22120.                                                                                 
  22121. save_prompt = prompt("ON")                                                      
  22122. "XPROC 0 TEST DEBUG FORCE NEW OLD BATCH BATCHIN(*) BATCHOUT(*)                  
  22123.          SERVER() GROUP() NEWSRC() OPTION() REGISTERSTATUS()"                   
  22124. if rc <> 0 then exit rc                                                         
  22125. call prompt save_prompt                                                         
  22126.                                                                                 
  22127. select                                                                          
  22128.  when new = "NEW" then do                                                       
  22129.   nnmprefix      = "NNMVS"     /* or use "new" (testing) parameters */          
  22130.   nnmpanelsuffix = "ISPPLIB"   /* or use "new" (testing) parameters */          
  22131.   nnmloadsuffix  = "LOAD"      /* or use "new" (testing) parameters */          
  22132.   nnmlmod        = "NNMMAIN"   /* or use "new" (testing) parameters */          
  22133.  end                                                                            
  22134.  when old = "OLD" then do                                                       
  22135.   nnmprefix      = "NNMVS"     /* or use "old" (backup) parameters */           
  22136.   nnmpanelsuffix = "ISPPLIB"   /* or use "old" (backup) parameters */           
  22137.   nnmloadsuffix  = "LOAD"      /* or use "old" (backup) parameters */           
  22138.   nnmlmod        = "NNMMAIN"   /* or use "old" (backup) parameters */           
  22139.  end                                                                            
  22140.  otherwise do                                                                   
  22141.   nnmprefix      = "NNMVS"                                                      
  22142.   nnmpanelsuffix = "ISPPLIB"                                                    
  22143.   nnmloadsuffix  = "LOAD"                                                       
  22144.   nnmlmod        = "NNMMAIN"                                                    
  22145.  end                                                                            
  22146. end                                                                             
  22147.                                                                                 
  22148. nnmpanel       = nnmprefix"."nnmpanelsuffix                                     
  22149. nnmload        = nnmprefix"."nnmloadsuffix                                      
  22150. nnmappl        = "ISR"                                                          
  22151. batchhelp      = "'"nnmprefix".HELP.TEXT'"                                      
  22152. nnmvswizard    = "Steve Bacher <seb@draper.com>"   /* next of kin */            
  22153. nnmvsmeister   = ""               /* TSOID of NNMVS's Big Brother */            
  22154.                                                                                 
  22155. trace off                                                                       
  22156. signal on novalue                                                               
  22157. libdeffed = 0                                                                   
  22158.                                                                                 
  22159. if batch = "" then do                                                           
  22160.  "ISPQRY"                                                                       
  22161.  if rc > 0 then do                                                              
  22162.   parse arg args                                                                
  22163.   parse source . . execname . execds .                                          
  22164.   if execds = "?" then                                                          
  22165.    icmd = "%"execname args                                                      
  22166.   else                                                                          
  22167.    icmd = "EX '"execds"("execname")'" quote(args)                               
  22168.   call startispf "NEWAPPL("nnmappl") CMD("icmd")"                               
  22169.   exit                                                                          
  22170.  end                                                                            
  22171. end                                                                             
  22172.                                                                                 
  22173. signal on failure                                                               
  22174. signal on halt                                                                  
  22175.                                                                                 
  22176. if option <> "" then do                                                         
  22177.  if length(option) <> 1 | pos(option,"TDB") <> 0 then do                        
  22178.   say "NNMVS: Invalid option, "option"."                                        
  22179.   exit 12                                                                       
  22180.  end                                                                            
  22181.  if server = "" then do                                                         
  22182.   say "NNMVS: SERVER is required when OPTION is specified."                     
  22183.   exit 12                                                                       
  22184.  end                                                                            
  22185.  if newsrc = "" then do                                                         
  22186.   say "NNMVS: NEWSRC is required when OPTION is specified."                     
  22187.   exit 12                                                                       
  22188.  end                                                                            
  22189.  if option = "G" & group = "" then do                                           
  22190.   say "NNMVS: GROUP is required when OPTION(G) is specified."                   
  22191.   exit 12                                                                       
  22192.  end                                                                            
  22193.  if registerstatus = "" then registerstatus = "PROMPT"                          
  22194. end                                                                             
  22195.                                                                                 
  22196. testparm = "-"                                                                  
  22197. if test  = "TEST"  then testparm = testparm || "t"                              
  22198. if debug = "DEBUG" then testparm = testparm || "d"                              
  22199. if batch = "BATCH" then testparm = testparm || "b"                              
  22200.                                                                                 
  22201. if find_iucvmult() <> 0 then do                                                 
  22202.  say,                                                                           
  22203. "A TCP/IP socket application may be active elsewhere in your session."          
  22204.  if force = "FORCE" then do                                                     
  22205.   say "Proceeding anyhow, because you specified the FORCE keyword."             
  22206.  end                                                                            
  22207.  else do                                                                        
  22208.   say "Please terminate the other application before trying this one."          
  22209.   say "Or, if you are sure it's OK, try again with the FORCE keyword."          
  22210.   exit 8                                                                        
  22211.  end                                                                            
  22212. end                                                                             
  22213.                                                                                 
  22214. if batch <> "" then call nnm_batch                                              
  22215. else do                                                                         
  22216.  call libdef                                                                    
  22217.  call nnm_dialog                                                                
  22218. end                                                                             
  22219.                                                                                 
  22220. cleanup:                                                                        
  22221. if libdeffed then call unlibdef                                                 
  22222. exit                                                                            
  22223.                                                                                 
  22224. error:    say "NNMVS:  Lossage has occurred."                                   
  22225.           say "Statement:" sourceline(sigl)                                     
  22226.           if nnmvswizard <> "" then say "Please notify" nnmvswizard"."          
  22227.           signal cleanup                                                        
  22228. failure:  say "NNMVS:  A failure has eventuated."                               
  22229.           say "Statement:" sourceline(sigl)                                     
  22230.           if nnmvswizard <> "" then say "Please notify" nnmvswizard"."          
  22231.           signal cleanup                                                        
  22232. halt:     say "NNMVS:  A halt has been detected."                               
  22233.           signal cleanup                                                        
  22234.                                                                                 
  22235. nnm_dialog:                                                                     
  22236.                                                                                 
  22237. /* SERVER(*) --> (USC) Leonard Woren's server-table dialog */                   
  22238.                                                                                 
  22239. if server = "*" | newsrc = "*" then do                                          
  22240.  nnmvsl_cmd = "%NNMVSL" new old                                                 
  22241.  address ISPEXEC "SELECT CMD("nnmvsl_cmd") PASSLIB NEWAPPL("nnmappl")"          
  22242.  return                                                                         
  22243. end                                                                             
  22244.                                                                                 
  22245. vputvars = ""                                                                   
  22246.                                                                                 
  22247. if server <> "" then do                                                         
  22248.  nnserver = server                                                              
  22249.  vputvars = vputvars "NNSERVER"                                                 
  22250. end                                                                             
  22251.                                                                                 
  22252. if group <> "" | option = "G" then do                                           
  22253.  nngroupi = group                                                               
  22254.  vputvars = vputvars "NNGROUPI"                                                 
  22255. end                                                                             
  22256.                                                                                 
  22257. if newsrc <> "" then do                                                         
  22258.  nnnewsrf = newsrc                                                              
  22259.  if left(newsrc,1) = "'" then nnnewsrc = strip(newsrc,"B","'")                  
  22260.  else nnnewsrc = sysvar("SYSPREF")"."newsrc                                     
  22261.  vputvars = vputvars "NNNEWSRF NNNEWSRC"                                        
  22262. end                                                                             
  22263.                                                                                 
  22264. if registerstatus <> "" then do                                                 
  22265.  nnregnng = left(registerstatus,1)                                              
  22266.  vputvars = vputvars "NNREGNNG"                                                 
  22267. end                                                                             
  22268.                                                                                 
  22269. if vputvars <> "" then do                                                       
  22270.  address ISPEXEC "VPUT ("vputvars") PROFILE"                                    
  22271. end                                                                             
  22272.                                                                                 
  22273. if option <> "" then do                                                         
  22274.  testparm = testparm || option                                                  
  22275. end                                                                             
  22276.                                                                                 
  22277. call let_me_know                                                                
  22278.                                                                                 
  22279. zerrmsg = ""                                                                    
  22280. zerrsm  = ""                                                                    
  22281. zerrlm  = ""                                                                    
  22282.                                                                                 
  22283. if nnmload = "" then do                                                         
  22284.  address ISPEXEC "SELECT NEWAPPL("nnmappl") PASSLIB" ,                          
  22285.                  "PGM("nnmlmod") PARM("testparm")"                              
  22286. end                                                                             
  22287. else do                                                                         
  22288.  command = "CALL '"nnmload"("nnmlmod")'" quote(testparm)                        
  22289.  address ISPEXEC "SELECT NEWAPPL("nnmappl") PASSLIB CMD("command")"             
  22290. end                                                                             
  22291.                                                                                 
  22292. if rc <> 0 then say "Return code from" nnmlmod "program is" rc                  
  22293.                                                                                 
  22294. address ISPEXEC "VGET (ZERRSM ZERRLM)"                                          
  22295. if zerrsm  <> "" then do                                                        
  22296.  say zerrmsg":" zerrsm                                                          
  22297.  say zerrlm                                                                     
  22298. end                                                                             
  22299.                                                                                 
  22300. return                                                                          
  22301.                                                                                 
  22302. nnm_batch:                                                                      
  22303.                                                                                 
  22304. if newsrc = "" then do                                                          
  22305.  say "NNMVS: NEWSRC is required when BATCH is specified."                       
  22306.  exit 12                                                                        
  22307. end                                                                             
  22308.                                                                                 
  22309. if server <> "" ,                                                               
  22310.  | group  <> "" ,                                                               
  22311.  | registerstatus <> "" ,                                                       
  22312.  | option <> "" then do                                                         
  22313.  say "NNMVS: SERVER, GROUP, OPTION, REGISTERSTATUS not valid",                  
  22314.             "when BATCH is specified."                                          
  22315.  exit 12                                                                        
  22316. end                                                                             
  22317.                                                                                 
  22318. address TSO "ALLOC FI(NNBATIN)  DA("batchin")  SHR REU"                         
  22319. if rc <> 0 then return                                                          
  22320. address TSO "ALLOC FI(NNBATOUT) DA("batchout") OLD REU"                         
  22321. if rc <> 0 then return                                                          
  22322. address TSO "ALLOC FI(NNBATHLP) DA("batchhelp") SHR REU"                        
  22323. if rc <> 0 then return                                                          
  22324. address TSO "ALLOC FI(NNNEWSRC) DA("newsrc")   OLD REU"                         
  22325. if rc <> 0 then return                                                          
  22326.                                                                                 
  22327. call let_me_know "BATCH"                                                        
  22328.                                                                                 
  22329. address TSO "CALL '"nnmload"("nnmlmod")'" quote(testparm)                       
  22330. nrc = rc                                                                        
  22331. address TSO "FREE FI(NNBATIN NNBATOUT NNBATHLP NNNEWSRC)"                       
  22332.                                                                                 
  22333. if nrc <> 0 then say "Return code from" nnmlmod "program is" nrc                
  22334.                                                                                 
  22335. return                                                                          
  22336.                                                                                 
  22337. let_me_know:                                                                    
  22338. if nnmvsmeister = "" | nnmvsmeister = userid() then return                      
  22339. parse arg letarg                                                                
  22340. parse source . . execname . execds .                                            
  22341. call outtrap "X."                                                               
  22342. address TSO,                                                                    
  22343.  "SEND" quote(execds"("execname")" letarg date("U") time()" "),                 
  22344.         "U("nnmvsmeister") LOGON"                                               
  22345. call outtrap "OFF"                                                              
  22346. return                                                                          
  22347.                                                                                 
  22348. libdef:                                                                         
  22349. if nnmpanel <> "" then do                                                       
  22350.  address ISPEXEC "LIBDEF ISPPLIB DATASET ID('"nnmpanel"')"                      
  22351.  if rc <> 0 then do; call ispf_error rc; exit rc; end                           
  22352. end                                                                             
  22353. if nnmload <> "" then do                                                        
  22354.  address ISPEXEC "LIBDEF ISPLLIB DATASET ID('"nnmload"')"                       
  22355.  if rc <> 0 then do; call ispf_error rc; exit rc; end                           
  22356. end                                                                             
  22357. libdeffed = 1                                                                   
  22358. return                                                                          
  22359.                                                                                 
  22360. unlibdef:                                                                       
  22361. if nnmload <> "" then do                                                        
  22362.  address ISPEXEC "LIBDEF ISPLLIB DATASET"                                       
  22363.  if rc <> 0 then call ispf_error rc                                             
  22364. end                                                                             
  22365. if nnmpanel <> "" then do                                                       
  22366.  address ISPEXEC "LIBDEF ISPPLIB DATASET"                                       
  22367.  if rc <> 0 then call ispf_error rc                                             
  22368. end                                                                             
  22369. libdeffed = 0                                                                   
  22370. return                                                                          
  22371.                                                                                 
  22372. ispf_error: parse arg ispfrc                                                    
  22373.                                                                                 
  22374. say "NNMVS: ISPF dialog service error detected..."                              
  22375. say                                                                             
  22376. say zerrmsg":" zerrsm                                                           
  22377. say zerrlm                                                                      
  22378. say                                                                             
  22379.                                                                                 
  22380. return ispfrc                                                                   
  22381.                                                                                 
  22382. /*                                                                              
  22383.  * The following function starts ISPF from READY mode.                          
  22384.  * Beware:  splitting the screen starts up an identical copy of the             
  22385.  *          application, which may not be desirable.                            
  22386.  */                                                                             
  22387.                                                                                 
  22388. startispf: parse arg string                                                     
  22389. "ISPSTART" string                                                               
  22390. return                                                                          
  22391.                                                                                 
  22392. /* The following function enquotes a string. */                                 
  22393.                                                                                 
  22394. quote: parse arg string                                                         
  22395. ix = 1                                                                          
  22396. do forever                                                                      
  22397.  ix = pos("'",string,ix)                                                        
  22398.  if ix = 0 then return "'"string"'"                                             
  22399.  string = insert("'",string,ix)                                                 
  22400.  ix=ix+2                                                                        
  22401. end                                                                             
  22402.                                                                                 
  22403. /* The following function scans the job pack queues for IUCVMULT and            
  22404.  * returns with an error code if IUCVMULT is already loaded under a             
  22405.  * different TCB. This can only happen under PIE MultiTSO or a                  
  22406.  * similar product that makes multiple job step TCB's.                          
  22407.  */                                                                             
  22408.                                                                                 
  22409. find_iucvmult: procedure                                                        
  22410.                                                                                 
  22411. call nnmfiucv                                                                   
  22412.                                                                                 
  22413. return result                                                                   
  22414.                                                                                 
  22415. ./ ENDUP                                                                        
  22416. ?!                                                                              
  22417. //H        EXEC NNLOAD,TRK1='5',TO='H'                                          
  22418. //SYSIN    DD DATA,DLM='?!'                                                     
  22419. ./   ADD NAME=NN,SSI=01630029                                                   
  22420.                                                                                 
  22421.  /********************************************************************/         
  22422.  /*                                                                  */         
  22423.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  22424.  /*                                                                  */         
  22425.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  22426.  /*                                                                  */         
  22427.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  22428.  /* including the implied warranties of merchantability and fitness, */         
  22429.  /* are expressly denied.                                            */         
  22430.  /*                                                                  */         
  22431.  /* Provided this copyright notice is included, this software may    */         
  22432.  /* be freely distributed and not offered for sale.                  */         
  22433.  /*                                                                  */         
  22434.  /* Changes or modifications may be made and used only by the maker  */         
  22435.  /* of same, and not further distributed.  Such modifications should */         
  22436.  /* be mailed to the author for consideration for addition to the    */         
  22437.  /* software and incorporation in subsequent releases.               */         
  22438.  /*                                                                  */         
  22439.  /********************************************************************/         
  22440.                                                                                 
  22441. /* --------------------- "nn.h" include member --------------------- */         
  22442.                                                                                 
  22443. #pragma linkage(NNMbrifr,FORTRAN)                                               
  22444. #pragma linkage(NNMbrifc,FORTRAN)                                               
  22445. #pragma linkage(ispexec,OS)                                                     
  22446. #pragma linkage(isplink,OS)                                                     
  22447. #pragma linkage(ikjeff18,OS)                                                    
  22448.                                                                                 
  22449. /****** Installation-customized defines. *****************************/         
  22450.                                                                                 
  22451. #include "nnuser.h"                                                             
  22452.                                                                                 
  22453. #ifndef  C370V1                                                                 
  22454. #ifndef  C370V2                                                                 
  22455. #ifndef  SASC                                                                   
  22456.  install_error_neither_C370V1_C370V2_nor_SASC_was_defined;                      
  22457. #endif                                                                          
  22458. #endif                                                                          
  22459. #endif                                                                          
  22460.                                                                                 
  22461. #ifndef  TCPIPV1                                                                
  22462. #ifndef  TCPIPV2                                                                
  22463.  install_error_neither_TCPIPV1_nor_TCPIPV2_was_defined;                         
  22464. #endif                                                                          
  22465. #endif                                                                          
  22466.                                                                                 
  22467. #define  MVS                                                                    
  22468.                                                                                 
  22469. /****** Clean up compiler warnings BEFORE time.h gets 'em ************/         
  22470.                                                                                 
  22471. #ifndef  SASC                                                                   
  22472. #define  localtime            LOCALTIM                                          
  22473. #endif                                                                          
  22474.                                                                                 
  22475. /****** Include all header files that are necessary. *****************/         
  22476.                                                                                 
  22477. #include <manifest.h>                                                           
  22478. #include <sys/types.h>                                                          
  22479. #include <sys/socket.h>                                                         
  22480. #include <netdb.h>                                                              
  22481. #include <netinet/in.h>                                                         
  22482. #include <sys/uio.h>                                                            
  22483. #include <sys/ioctl.h>                                                          
  22484. /*                                                                              
  22485. #include <tcperrno.h>                                                           
  22486. */                                                                              
  22487. #include <ctype.h>                                                              
  22488. #include <errno.h>                                                              
  22489. #include <limits.h>                                                             
  22490. #include <setjmp.h>                                                             
  22491. #include <stdio.h>                                                              
  22492. #include <stdarg.h>                                                             
  22493. #include <stdlib.h>                                                             
  22494. #include <string.h>                                                             
  22495. #include <stddef.h>                                                             
  22496. #include <time.h>                                                               
  22497. /*                                                                              
  22498. #include <signal.h>                                                             
  22499. */                                                                              
  22500.                                                                                 
  22501. #ifndef  SASC                                                                   
  22502. #include <ctest.h>                                                              
  22503. #endif                                                                          
  22504.                                                                                 
  22505. #ifdef   SASC                                                                   
  22506. #include "nnsasc.h"                                                             
  22507. #endif                                                                          
  22508.                                                                                 
  22509. /****** Version-dependent stuff **************************************/         
  22510.                                                                                 
  22511. #ifdef   C370V1                                                                 
  22512. #undef   FETCH                                                                  
  22513. #endif                                                                          
  22514.                                                                                 
  22515. #ifdef   C370V2                                                                 
  22516. #define  FETCH                                                                  
  22517. #endif                                                                          
  22518.                                                                                 
  22519. #ifdef   TCPIPV1                                                                
  22520. #define  TCP_DEBUG            tcp_debug                                         
  22521. #endif                                                                          
  22522.                                                                                 
  22523. #ifdef   TCPIPV2                                                                
  22524. #define  TCP_DEBUG            sock_debug                                        
  22525. #endif                                                                          
  22526.                                                                                 
  22527. #ifdef   DEBUG                                                                  
  22528. #define  TCP_DEBUG_ON         TCP_DEBUG(1)                                      
  22529. #define  TCP_DEBUG_OFF        TCP_DEBUG(0)                                      
  22530. #else                                                                           
  22531. #define  TCP_DEBUG_ON         /* */                                             
  22532. #define  TCP_DEBUG_OFF        /* */                                             
  22533. #endif                                                                          
  22534.                                                                                 
  22535. /****** Preprocessor bookkeeping *************************************/         
  22536.                                                                                 
  22537. #define  Bool                 char                                              
  22538. #define  Fool                 unsigned int /* for function arguments */         
  22539.                                                                                 
  22540. #define  COMMANDSIZE          12                                                
  22541.                                                                                 
  22542. #define  READ_BYTES           1024                                              
  22543. #define  SERVER_BUF_MSGSIZE   1024                                              
  22544. #define  CLIENT_BUF_MSGSIZE   1024                                              
  22545. #define  TEXT_BYTES           1024                                              
  22546. #define  INTERNET_SIZE        256                                               
  22547.                                                                                 
  22548. #define  GROUP_NAME_SIZE      255                                               
  22549.                                                                                 
  22550. #define  NNTP_PORT_NUMBER     119                                               
  22551.                                                                                 
  22552. #define  SOCKET_GETCHAR_ERROR (-1)                                              
  22553. #define  SOCKET_NO_MORE       (-2)                                              
  22554. #define  SOCKET_READ_NOTHING  (-3)                                              
  22555.                                                                                 
  22556. #define  NO_NNTP_MESSAGE_NUM  (-1)                                              
  22557. #define  NO_VALUE             (-1)                                              
  22558. #define  PHONY_NEWS_ARTICLE   (struct newsarticle *)(-1)                        
  22559.                                                                                 
  22560. #define  UNREAD_THIS_ARTICLE  (-1)                                              
  22561. #define  NEXT_THREAD_ARTICLE  (-2)                                              
  22562. #define  PREV_THREAD_ARTICLE  (-3)                                              
  22563. #define  FIRST_THREAD_ARTICLE (-4)                                              
  22564. #define  LAST_THREAD_ARTICLE  (-5)                                              
  22565. #define  NEW_THREAD_ARTICLE   (-6)                                              
  22566.                                                                                 
  22567. #define  Rstruc               register struct                                   
  22568.                                                                                 
  22569. #define  EQUAL                !strcmp                                           
  22570. #define  UNEQUAL              strcmp                                            
  22571.                                                                                 
  22572. #define  VARK                 char                                              
  22573. #define  V_STATUS(X,Y)        (X)->article_vector[(Y)-1]                        
  22574. #define  V_LENGTH(X)          (X)->article_vector_len                           
  22575.                                                                                 
  22576. #define  V_READ               'R'                                               
  22577. #define  V_UNREAD             'U'                                               
  22578. #define  V_MISSING_READ       'M'                                               
  22579. #define  V_MISSING_UNREAD     'N'                                               
  22580.                                                                                 
  22581. #define  NEWSRC_ORDER         'N'                                               
  22582. #define  NNTP_LIST_ORDER      'L'                                               
  22583. #define  ALPHABETICAL_ORDER   'A'                                               
  22584.                                                                                 
  22585. #define  FIND_NEXT            'N'                                               
  22586. #define  FIND_FIRST           'F'                                               
  22587. #define  FIND_LAST            'L'                                               
  22588. #define  FIND_PREV            'P'                                               
  22589.                                                                                 
  22590. #define  SELECTION_ALL        'A'                                               
  22591. #define  SELECTION_REG        'R'                                               
  22592. #define  SELECTION_NNTP       'P'                                               
  22593. #define  SELECTION_GROUP      'G'                                               
  22594. #define  SELECTION_LIST       'L'                                               
  22595. #define  SELECTION_NEWG       'N'                                               
  22596. #define  SELECTION_OPTS       'O'                                               
  22597. #define  SELECTION_EXIT       'X'                                               
  22598.                                                                                 
  22599. #define  CARRIAGE_RETURN      ('\r')                                            
  22600.                                                                                 
  22601. #ifdef   MVS                                                                    
  22602. #ifdef   I370                                                                   
  22603. #define  LINE_FEED            (0x15)                                            
  22604. #else                                                                           
  22605. #define  LINE_FEED            (0x25)                                            
  22606. #endif                                                                          
  22607. #else                                                                           
  22608. #define  LINE_FEED            (0x0a)                                            
  22609. #endif                                                                          
  22610.                                                                                 
  22611. #ifdef   MVS                                                                    
  22612. #ifndef  I370                                                                   
  22613. #define  etoa(x)              ebcdictoascii[x]                                  
  22614. #define  atoe(x)              asciitoebcdic[x]                                  
  22615. #define  ebcdictoascii        ebcdicto                                          
  22616. #define  asciitoebcdic        asciitoe                                          
  22617. #else                                                                           
  22618. #define  etoa                 htoncs                                            
  22619. #define  atoe                 ntohcs                                            
  22620. #endif                                                                          
  22621. #endif                                                                          
  22622.                                                                                 
  22623. #ifdef   FETCH                                                                  
  22624. #define  ISPLINK              (np->isplink_pointer)                             
  22625. #define  ISPEXEC              (np->ispexec_pointer)                             
  22626. #else                                                                           
  22627. #define  ISPLINK              isplink                                           
  22628. #define  ISPEXEC              ispexec                                           
  22629. #endif                                                                          
  22630.                                                                                 
  22631. #define  DATAOUT_LOW          0x01                                              
  22632. #define  DATAOUT_HIGH         0x02                                              
  22633. #define  DATAIN_LOW           0x03                                              
  22634. #define  DATAIN_HIGH          0x04                                              
  22635. #define  DATAOUT_BLUE         DATAOUT_LOW                                       
  22636. #define  DATAOUT_GREEN        0x05                                              
  22637. #define  DATAOUT_PINK         0x06                                              
  22638. #define  DATAOUT_RED          0x07                                              
  22639. #define  DATAOUT_TURQ         0x08                                              
  22640. #define  DATAOUT_WHITE        DATAOUT_HIGH                                      
  22641. #define  DATAOUT_YELLOW       0x09                                              
  22642. #define  DATAIN_BLUE          0x0a                                              
  22643. #define  DATAIN_GREEN         DATAIN_LOW                                        
  22644. #define  DATAIN_PINK          0x0b                                              
  22645. #define  DATAIN_RED           DATAIN_HIGH                                       
  22646. #define  DATAIN_TURQ          0x0c                                              
  22647. #define  DATAIN_WHITE         0x0d                                              
  22648. #define  DATAIN_YELLOW        0x0e                                              
  22649.                                                                                 
  22650. #define  S99VRBAL  0x01             /* ALLOCATION                    */         
  22651. #define  S99VRBUN  0x02             /* UNALLOCATION                  */         
  22652. #define  S99VRBCC  0x03             /* CONCATENATION                 */         
  22653. #define  S99VRBDC  0x04             /* DECONCATENATION               */         
  22654. #define  S99VRBRI  0x05             /* REMOVE IN-USE                 */         
  22655. #define  S99VRBDN  0x06             /* DDNAME ALLOCATION             */         
  22656. #define  S99VRBIN  0x07             /* INFORMATION RETRIEVAL         */         
  22657. #define  S99NOCNV  0x40             /* ALLOC FUNCTION-DO NOT USE AN  */         
  22658.                                     /* EXISTING ALLOCATION TO SATISFY*/         
  22659.                                     /* THE REQUEST                   */         
  22660. #define  DALDDNAM   0x0001          /* DDNAME                        */         
  22661. #define  DALDSNAM   0x0002          /* DSNAME                        */         
  22662. #define  DALMEMBR   0x0003          /* MEMBER NAME                   */         
  22663. #define  DALSTATS   0x0004          /* DATA SET STATUS               */         
  22664. #define  DALNDISP   0x0005          /* DATA SET DISPOSITION          */         
  22665. #define  DALBLKLN   0x0009          /* BLOCK LENGTH                  */         
  22666. #define  DALPRIME   0x000a          /* PRIMARY SPACE ALLOCATION      */         
  22667. #define  DALSECND   0x000b          /* SECONDARY SPACE ALLOCATION    */         
  22668. #define  DALDIR     0x000c          /* DIRECTORY BLOCK ALLOCATION    */         
  22669. #define  DALBLKSZ   0x0030          /* DCB BLOCKSIZE                 */         
  22670. #define  DALDSORG   0x003c          /* DATA SET ORGANIZATION         */         
  22671. #define  DALLRECL   0x0042          /* DCB LOGICAL RECORD LENGTH     */         
  22672. #define  DALRECFM   0x0049          /* DCB RECORD FORMAT             */         
  22673. #define  DALPERMA   0x0052          /* PERMANENTLY ALLOCATED ATTRIB  */         
  22674. #define  DALRTDDN   0x0055          /* RETURN DDNAME                 */         
  22675. #define  DALRTDSN   0x0056          /* RETURN DSNAME                 */         
  22676. #define  DALRTORG   0x0057          /* RETURN D.S. ORGANIZATION      */         
  22677. #define  DUNDDNAM   0x0001          /* DDNAME                        */         
  22678. #define  DUNDSNAM   0x0002          /* DSNAME                        */         
  22679. #define  DUNUNALC   0x0007          /* UNALLOC OPTION                */         
  22680.                                                                                 
  22681. #define  SHR        0x08                                                        
  22682. #define  NEW        0x04                                                        
  22683. #define  MOD        0x02                                                        
  22684. #define  OLD        0x01                                                        
  22685. #define  KEEP       0x08                                                        
  22686. #define  DELETE     0x04                                                        
  22687. #define  CATLG      0x02                                                        
  22688. #define  UNCATLG    0x01                                                        
  22689. #define  RECFM_F    0x80                                                        
  22690. #define  RECFM_V    0x40                                                        
  22691. #define  RECFM_U    0xc0                                                        
  22692. #define  RECFM_D    0x20                                                        
  22693. #define  RECFM_T    0x20                                                        
  22694. #define  RECFM_B    0x10                                                        
  22695. #define  RECFM_S    0x08                                                        
  22696. #define  RECFM_A    0x04                                                        
  22697. #define  RECFM_M    0x02                                                        
  22698. #define  RECFM_FB   (RECFM_F | RECFM_B)                                         
  22699. #define  RECFM_VB   (RECFM_V | RECFM_B)                                         
  22700. #define  DSORG_PS   0x4000                                                      
  22701. #define  DSORG_PO   0x0200                                                      
  22702.                                                                                 
  22703. /************************ Newsgroup status ***************************/         
  22704.                                                                                 
  22705. #define NO_SUCH_GROUP             0x80                                          
  22706. #define NEW_GROUP                 0x40                                          
  22707. #define GROUP_FROM_NEWSRC         0x20                                          
  22708. #define GROUP_LISTED              0x10                                          
  22709. #define GROUP_SELECTED            0x08                                          
  22710. #define GROUP_RETRIEVED           0x04                                          
  22711. #define GROUP_ERROR               0x02                                          
  22712. #define GROUP_IN_TABLE            0x01                                          
  22713.                                                                                 
  22714. #define NoSuchGroup(X)            (X->status & NO_SUCH_GROUP)                   
  22715. #define NewGroup(X)               (X->status & NEW_GROUP)                       
  22716. #define GroupFromNewsrc(X)        (X->status & GROUP_FROM_NEWSRC)               
  22717. #define GroupListed(X)            (X->status & GROUP_LISTED)                    
  22718. #define GroupSelected(X)          (X->status & GROUP_SELECTED)                  
  22719. #define GroupRetrieved(X)         (X->status & GROUP_RETRIEVED)                 
  22720. #define GroupError(X)             (X->status & GROUP_ERROR)                     
  22721. #define GroupInTable(X)           (X->status & GROUP_IN_TABLE)                  
  22722.                                                                                 
  22723. #define SetNoSuchGroup(X)         X->status |= NO_SUCH_GROUP                    
  22724. #define SetNewGroup(X)            X->status |= NEW_GROUP                        
  22725. #define SetGroupFromNewsrc(X)     X->status |= GROUP_FROM_NEWSRC                
  22726. #define SetGroupListed(X)         X->status |= GROUP_LISTED                     
  22727. #define SetGroupSelected(X)       X->status |= GROUP_SELECTED                   
  22728. #define SetGroupRetrieved(X)      X->status |= GROUP_RETRIEVED                  
  22729. #define SetGroupError(X)          X->status |= GROUP_ERROR                      
  22730. #define SetGroupInTable(X)        X->status |= GROUP_IN_TABLE                   
  22731.                                                                                 
  22732. #define OffNoSuchGroup(X)         X->status &= ~NO_SUCH_GROUP                   
  22733. #define OffNewGroup(X)            X->status &= ~NEW_GROUP                       
  22734. #define OffGroupFromNewsrc(X)     X->status &= ~GROUP_FROM_NEWSRC               
  22735. #define OffGroupListed(X)         X->status &= ~GROUP_LISTED                    
  22736. #define OffGroupSelected(X)       X->status &= ~GROUP_SELECTED                  
  22737. #define OffGroupRetrieved(X)      X->status &= ~GROUP_RETRIEVED                 
  22738. #define OffGroupError(X)          X->status &= ~GROUP_ERROR                     
  22739. #define OffGroupInTable(X)        X->status &= ~GROUP_IN_TABLE                  
  22740.                                                                                 
  22741. #define GroupListedOnly(X)        (GroupListed(X) && !GroupSelected(X))         
  22742. #define GroupFromNNTP(X)          (GroupListed(X) || GroupSelected(X))          
  22743. #define GroupFromNewsrcOnly(X)    (GroupFromNewsrc(X) && \                      
  22744.                                    !GroupListed(X) && \                         
  22745.                                    !GroupSelected(X))                           
  22746. #define BogusGroup(X)             (!GroupListed(X) && !GroupSelected(X))        
  22747. #define ClearGroupStatus(X)       X->status = 0x00                              
  22748. #define NullGroupStatus(X)        (X->status == 0x00)                           
  22749.                                                                                 
  22750. /************************* Article status ****************************/         
  22751.                                                                                 
  22752. #define NO_SUCH_ARTICLE           0x80                                          
  22753. #define ARTICLE_ABSENT            0x40                                          
  22754. #define ARTICLE_ERROR             0x20                                          
  22755. #define ARTICLE_BAD_DATA          0x10                                          
  22756. #define ARTICLE_HEAD_RETRIEVED    0x08                                          
  22757. #define ARTICLE_BODY_RETRIEVED    0x04                                          
  22758. #define ARTICLE_IN_TABLE          0x02                                          
  22759.                                                                                 
  22760. #define ARTICLE_RETRIEVED         (ARTICLE_HEAD_RETRIEVED | \                   
  22761.                                    ARTICLE_BODY_RETRIEVED)                      
  22762.                                                                                 
  22763. #define NoSuchArticle(X)          ((X)->status & NO_SUCH_ARTICLE)               
  22764. #define ArticleAbsent(X)          ((X)->status & ARTICLE_ABSENT)                
  22765. #define ArticleError(X)           ((X)->status & ARTICLE_ERROR)                 
  22766. #define ArticleBadData(X)         ((X)->status & ARTICLE_BAD_DATA)              
  22767. #define ArticleHeadRetrieved(X)   ((X)->status & ARTICLE_HEAD_RETRIEVED)        
  22768. #define ArticleBodyRetrieved(X)   ((X)->status & ARTICLE_BODY_RETRIEVED)        
  22769. #define ArticleInTable(X)         ((X)->status & ARTICLE_IN_TABLE)              
  22770.                                                                                 
  22771. #define SetNoSuchArticle(X)        (X)->status |= NO_SUCH_ARTICLE               
  22772. #define SetArticleAbsent(X)        (X)->status |= ARTICLE_ABSENT                
  22773. #define SetArticleError(X)         (X)->status |= ARTICLE_ERROR                 
  22774. #define SetArticleBadData(X)       (X)->status |= ARTICLE_BAD_DATA              
  22775. #define SetArticleHeadRetrieved(X) (X)->status |= ARTICLE_HEAD_RETRIEVED        
  22776. #define SetArticleBodyRetrieved(X) (X)->status |= ARTICLE_BODY_RETRIEVED        
  22777. #define SetArticleInTable(X)       (X)->status |= ARTICLE_IN_TABLE              
  22778.                                                                                 
  22779. #define OffNoSuchArticle(X)        (X)->status &=~NO_SUCH_ARTICLE               
  22780. #define OffArticleAbsent(X)        (X)->status &=~ARTICLE_ABSENT                
  22781. #define OffArticleError(X)         (X)->status &=~ARTICLE_ERROR                 
  22782. #define OffArticleBadData(X)       (X)->status &=~ARTICLE_BAD_DATA              
  22783. #define OffArticleHeadRetrieved(X) (X)->status &=~ARTICLE_HEAD_RETRIEVED        
  22784. #define OffArticleBodyRetrieved(X) (X)->status &=~ARTICLE_BODY_RETRIEVED        
  22785. #define OffArticleInTable(X)       (X)->status &=~ARTICLE_IN_TABLE              
  22786.                                                                                 
  22787. #define ArticleRetrieved(X)       ((X)->status & ARTICLE_RETRIEVED)             
  22788. #define SetArticleRetrieved(X)     (X)->status |= ARTICLE_RETRIEVED             
  22789. #define OffArticleRetrieved(X)     (X)->status &= ~ARTICLE_RETRIEVED            
  22790.                                                                                 
  22791. #define ClearArticleStatus(X)     (X)->status &= ARTICLE_IN_TABLE               
  22792. #define NullArticleStatus(X)      ((X)->status & ~ARTICLE_IN_TABLE)             
  22793.                                                                                 
  22794. /****** Data and structure definitions. ******************************/         
  22795.                                                                                 
  22796. typedef  struct   _textunit     TEXTUNIT;                                       
  22797.                                                                                 
  22798. typedef unsigned int IPADDRESS;                                                 
  22799.                                                                                 
  22800. enum socket_retval  {                                                           
  22801.                      SERVER_READ_OK,                                            
  22802.                      SERVER_READ_ERROR,                                         
  22803.                      SERVER_BUFFER_ERROR,                                       
  22804.                      SERVER_NO_MORE                                             
  22805.                     };                                                          
  22806.                                                                                 
  22807. enum display_retval {                                                           
  22808.                      DISPLAY_REPEAT,                                            
  22809.                      DISPLAY_EXIT,                                              
  22810.                      DISPLAY_ERROR,                                             
  22811.                      DISPLAY_FAILURE                                            
  22812.                     };                                                          
  22813.                                                                                 
  22814. enum article_action {                                                           
  22815.                      NO_ACTION,                                                 
  22816.                      READ,                                                      
  22817.                      RETRIEVED,                                                 
  22818.                      EXTRACTED,                                                 
  22819.                      PRINTED,                                                   
  22820.                      UNREAD,                                                    
  22821.                      MISSING,                                                   
  22822.                      ERROR,                                                     
  22823.                      CANCELLED                                                  
  22824.                     };                                                          
  22825.                                                                                 
  22826. enum data_set_type  {                                                           
  22827.                      PDS,                                                       
  22828.                      SEQ,                                                       
  22829.                      UNK                                                        
  22830.                     };                                                          
  22831.                                                                                 
  22832. enum user_option    {                                                           
  22833.                      OPTION_ALL,                                                
  22834.                      OPTION_HEADER,                                             
  22835.                      OPTION_OTHER,                                              
  22836.                      OPTION_VIEW                                                
  22837.                     };                                                          
  22838.                                                                                 
  22839. enum list_option    {                                                           
  22840.                      LIST_ALL,                                                  
  22841.                      LIST_NEW                                                   
  22842.                     };                                                          
  22843.                                                                                 
  22844. struct textline    {                                                            
  22845.                     struct textline    *next;                                   
  22846.                     short               text_length;                            
  22847.                     short               tab_expanded_text_length;               
  22848.                     char               *tab_expanded_text;                      
  22849.                     char                text[1];  /* dummy */                   
  22850.                    };                                                           
  22851.                                                                                 
  22852. struct texthdr     {                                                            
  22853.                     int                   text_line_count;                      
  22854.                     struct textline      *text_body_line;                       
  22855.                     short                 text_max_length;                      
  22856.                     short                 text_max_tab_expanded_length;         
  22857.                     struct textline      *first_text_line;                      
  22858.                     struct textline      *current_text_line;                    
  22859.                     struct textline      *last_text_line;                       
  22860.                    };                                                           
  22861.                                                                                 
  22862. struct newsarticle {                                                            
  22863.                     char                 *from;                                 
  22864.                     char                 *subject;                              
  22865.                     char                 *date;                                 
  22866.                     char                 *message_id;                           
  22867.                     char                 *csubject;                             
  22868.                     int                   number;                               
  22869.                     enum article_action   action;                               
  22870.                     char                  status;                               
  22871.                     struct texthdr        thdr;                                 
  22872.                    };                                                           
  22873.                                                                                 
  22874. struct newsgroup   {                                                            
  22875.                     struct newsgroup     *next;                                 
  22876.                     struct newsgroup     *next2;                                
  22877.                     struct newsarticle   *first_article;                        
  22878.                     struct newsarticle   *fake_last_article;                    
  22879.                     struct newsarticle   *real_last_article;                    
  22880.                                   char   *saved_newsrc_line;                    
  22881.                                   VARK   *article_vector;                       
  22882.                                    int    article_vector_len;                   
  22883.                                    int    fake_article_count;                   
  22884.                                    int    real_article_count;                   
  22885.                                    int    fake_first_article_number;            
  22886.                                    int    real_first_article_number;            
  22887.                                    int    fake_last_article_number;             
  22888.                                    int    real_last_article_number;             
  22889.                                    int    fake_unread_count;                    
  22890.                                    int    real_unread_count;                    
  22891.                                    int    registered;                           
  22892.                                   char    status;                               
  22893.                                   char    saved_newsrc_data[9];                 
  22894.                                   char    name       [GROUP_NAME_SIZE];         
  22895.                    };                                                           
  22896.                                                                                 
  22897. struct cmddesc   {                                                              
  22898.                   char    command_name[COMMANDSIZE];                            
  22899.                   Bool    (*command_processor)();                               
  22900.                  };                                                             
  22901.                                                                                 
  22902. struct seldesc   {                                                              
  22903.                   char    selection_code;                                       
  22904.                   Bool    (*selection_processor)();                             
  22905.                  };                                                             
  22906.                                                                                 
  22907. struct tabledesc {                                                              
  22908.                   char   *command_variable;                                     
  22909.         struct cmddesc   *first_cmddesc;                                        
  22910.         struct seldesc   *first_seldesc;                                        
  22911.                  };                                                             
  22912.                                                                                 
  22913. struct _textunit {                                                              
  22914.                   unsigned short         key;                                   
  22915.                   unsigned short         num;                                   
  22916.                   struct {                                                      
  22917.                           unsigned short len;                                   
  22918.                           char           prm[80];                               
  22919.                          }               ent;                                   
  22920.                  };                                                             
  22921.                                                                                 
  22922. struct extraction {                                                             
  22923.                    int                   from_article_number;                   
  22924.                    int                   to_article_number;                     
  22925.                    int                   article_count;                         
  22926.                    enum data_set_type    mode;                                  
  22927.                    Bool                  appending;                             
  22928.                    Bool                  blanking;                              
  22929.                    Bool                  tab_expanding;                         
  22930.                    char                  panelname     [9];                     
  22931.                    char                  dsname       [65];                     
  22932.                    char                  separator    [81];                     
  22933.                    char                  member_prefix [9];                     
  22934.                    char                  ddname        [9];                     
  22935.                   };                                                            
  22936.                                                                                 
  22937. struct countdown  {                                                             
  22938.                    Bool                  do_update;                             
  22939.                    int                   done;                                  
  22940.                    int                   to_do;                                 
  22941.                   };                                                            
  22942.                                                                                 
  22943. struct nncb {                                                                   
  22944.              char    *server_buf;                                               
  22945.              char    *client_buf;                                               
  22946.              char    *nntp_command;                                             
  22947.              char    *nntp_message_text;                                        
  22948.              char    *extract_separator_line;                                   
  22949.  struct newsgroup    *first_newsgroup;                                          
  22950.  struct newsgroup    *current_newsgroup;                                        
  22951.  struct newsgroup    *last_newsgroup;                                           
  22952.  struct newsgroup    *first_newsgroup_alt;                                      
  22953.  struct newsgroup    *last_added_newsgroup;                                     
  22954.  struct newsarticle  *article_being_viewed;                                     
  22955.  struct newsarticle  *another_article;                                          
  22956.  struct newsarticle  *top_article;                                              
  22957.  struct tabledesc    *newsgroup_display_table_address;                          
  22958.  struct tabledesc    *article_display_table_address;                            
  22959.    struct texthdr    *brifp;                                                    
  22960.              FILE    *debug_file;                                               
  22961.              FILE    *newsrc_file;                                              
  22962.              FILE    *extract_file;                                             
  22963.              FILE    *batch_infile;                                             
  22964.              FILE    *batch_outfile;                                            
  22965.              void    *batch_hook;                                               
  22966. #ifdef FETCH                                                                    
  22967.               int   (*isplink_pointer)();                                       
  22968.               int   (*ispexec_pointer)();                                       
  22969. #endif                                                                          
  22970.               int     ispfrc;                                                   
  22971.               int     nntp_message_num;                                         
  22972.               int     socknum;                                                  
  22973.               int     g_bytes_returned;                                         
  22974.               int     g_buf_index;                                              
  22975.               int     new_newsgroup_count;                                      
  22976.               int     article_rows;                                             
  22977.               int     updatefreq;      /* ddi */                                
  22978.               int     brif_previous_recno;                                      
  22979.    struct texthdr     thdr;                                                     
  22980.         IPADDRESS     client_ip_address;                                        
  22981.         IPADDRESS     server_ip_address;                                        
  22982.              time_t   lasttime;           /* ddi */                             
  22983.              time_t   firstime;           /* ddi */                             
  22984.              Bool     test_mode;                                                
  22985.              Bool     debug_mode;                                               
  22986.              Bool     batch_mode;                                               
  22987.              Bool     quit;                                                     
  22988.              Bool     time_to_go_home;                                          
  22989.              Bool     server_has_something_pending;                             
  22990.              Bool     server_finished_replying;                                 
  22991.              Bool     sending_text;                                             
  22992.              Bool     receiving_text;                                           
  22993.              Bool     something_to_print;                                       
  22994.              Bool     dont_read;                                                
  22995.              Bool     connected_to_server;                                      
  22996.              Bool     connection_broken;                                        
  22997.              Bool     closing_connection;                                       
  22998.              Bool     reconnect_in_progress;                                    
  22999.              Bool     posting_allowed;                                          
  23000.              Bool     newsgroup_selected;                                       
  23001.              Bool     newsgroup_not_found;                                      
  23002.              Bool     newsgroup_order_changed;                                  
  23003.              Bool     brand_new_newsrc;                                         
  23004.              Bool     newsgroup_criterion_changed;                              
  23005.              Bool     show_all_newsgroups;                                      
  23006.              Bool     following_up;                                             
  23007.              Bool     extract_tab_expanding;                                    
  23008.              Bool     extract_appending;                                        
  23009.              Bool     extract_blank_before_separator;                           
  23010.              Bool     extract_write_error;                                      
  23011.              Bool     extract_close_error;                                      
  23012.              Bool     please_locate_group;                                      
  23013.              Bool     please_find_group;                                        
  23014.              Bool     repeat_find;                                              
  23015.              Bool     article_criterion_changed;                                
  23016.              Bool     article_repeat_find;                                      
  23017.              Bool     article_text_not_found;                                   
  23018.              Bool     warn_overwrite;                                           
  23019.              Bool     warn_append;                                              
  23020.              Bool     article_error_found;                                      
  23021.              Bool     show_all_articles;                                        
  23022.              Bool     update_adding_newsgroups;                                 
  23023.              Bool     update_rewriting_newsrc;                                  
  23024.              Bool     update_retrieving_articles;                               
  23025.              Bool     bypass_header_retrieval;                                  
  23026.              Bool     unread_articles_only;                                     
  23027.              Bool     setmsg;                                                   
  23028.              Bool     newsgroup_autoscroll;                                     
  23029.              Bool     article_autoscroll;                                       
  23030.              Bool     sort_by_subject;                                          
  23031.              Bool     brif_debug;                                               
  23032.              char     newsgroup_order;                                          
  23033.              char     find_option;                                              
  23034.              char     article_find_option;                                      
  23035.              char     preselection;                                             
  23036.              char     barchar;            /* ddi */                             
  23037.              char     newsrc_to_open      [ 12];                                
  23038.              char     nnrfcopt            [  2];                                
  23039.              char     nnrfcinc            [256];                                
  23040.              char     nnrfcexc            [256];                                
  23041.              char     maildsn             [ 64];                                
  23042.              char     messageid           [128];                                
  23043.              char     nnregnng            [  9];                                
  23044.              char     nngroup             [GROUP_NAME_SIZE+1];                  
  23045.              char     nnserver            [MAXHOSTNAMELEN+1];                   
  23046.              char     nnclient            [MAXHOSTNAMELEN+1];                   
  23047.              char     client_hostname     [MAXHOSTNAMELEN+1];                   
  23048.              char     client_ip_addrstr   [16];                                 
  23049.              char     server_hostname     [MAXHOSTNAMELEN+1];                   
  23050.              char     server_ip_addrstr   [16];                                 
  23051.              char     g_buf               [READ_BYTES];                         
  23052.              char     locate_string       [GROUP_NAME_SIZE+1];                  
  23053.              char     only_string         [GROUP_NAME_SIZE+1];                  
  23054.              char     find_string         [GROUP_NAME_SIZE+1];                  
  23055.              char     article_only_string [GROUP_NAME_SIZE+1];                  
  23056.              char     article_find_string [GROUP_NAME_SIZE+1];                  
  23057.              char     lastNGdate          [7];      /* ddi */                   
  23058.              char     lastNGtime          [7];      /* ddi */                   
  23059.              char     selsubj             [81];     /* ddi */                   
  23060.             };                                                                  
  23061.                                                                                 
  23062. #ifdef MVS                                                                      
  23063. #ifndef I370                                                                    
  23064. extern char                 ebcdictoascii[];                                    
  23065. extern char                 asciitoebcdic[];                                    
  23066. #endif                                                                          
  23067. #endif                                                                          
  23068.                                                                                 
  23069. #ifndef FETCH                                                                   
  23070. extern int                  isplink();                                          
  23071. extern int                  ispexec();                                          
  23072. #endif                                                                          
  23073.                                                                                 
  23074. #define  NOTIFY_MSG   1                                                         
  23075. #define  WARNING_MSG  2                                                         
  23076. #define  CRITICAL_MSG 3                                                         
  23077.                                                                                 
  23078. #define  WARN1(X)           NNMpmsg(np,NOTIFY_MSG,NULL,X)                       
  23079. #define  WARN2(X,Y)         NNMpmsg(np,NOTIFY_MSG,NULL,X,Y)                     
  23080. #define  WARN3(X,Y,Z)       NNMpmsg(np,NOTIFY_MSG,NULL,X,Y,Z)                   
  23081. #define  WARN4(X,Y,Z,W)     NNMpmsg(np,NOTIFY_MSG,NULL,X,Y,Z,W)                 
  23082. #define  ERR1(X)            NNMpmsg(np,WARNING_MSG,NULL,X)                      
  23083. #define  ERR2(X,Y)          NNMpmsg(np,WARNING_MSG,NULL,X,Y)                    
  23084. #define  ERR3(X,Y,Z)        NNMpmsg(np,WARNING_MSG,NULL,X,Y,Z)                  
  23085. #define  ERR4(X,Y,Z,W)      NNMpmsg(np,WARNING_MSG,NULL,X,Y,Z,W)                
  23086. #define  CRIT1(X)           NNMpmsg(np,CRITICAL_MSG,NULL,X)                     
  23087. #define  CRIT2(X,Y)         NNMpmsg(np,CRITICAL_MSG,NULL,X,Y)                   
  23088. #define  CRIT3(X,Y,Z)       NNMpmsg(np,CRITICAL_MSG,NULL,X,Y,Z)                 
  23089.                                                                                 
  23090. #define  MSG(X)             (MSG_is_obsolete,)                                  
  23091.                                                                                 
  23092. #define  GETMAIN(Ptr,Typ,Siz,For) \                                             
  23093.          NNMgetm(np,(char **)&(Ptr),(sizeof(Typ))*(Siz),For)                    
  23094.                                                                                 
  23095. #define  FREEMAIN(Ptr,For)    if (Ptr) {NNMfreem(np,(char *)Ptr,For);}          
  23096.                                                                                 
  23097. #ifndef I370                                                                    
  23098.                                                                                 
  23099. #define  OPEN_TEXT_FILE_FOR_WRITE(F)  \                                         
  23100.          fopen((F),"w,recfm=vb,lrecl=259,blksize=6233")                         
  23101.                                                                                 
  23102. #define  OPEN_TEXT_FILE_FOR_APPEND(F)  \                                        
  23103.          fopen((F),"a,recfm=vb,lrecl=259,blksize=6233")                         
  23104.                                                                                 
  23105. #define  OPEN_TEXT_FILE_FOR_WRITE_OR_APPEND(F,B)  \                             
  23106.          fopen((F),(B) ? "a,recfm=vb,lrecl=259,blksize=6233"  \                 
  23107.                        : "w,recfm=vb,lrecl=259,blksize=6233")                   
  23108.                                                                                 
  23109. #else                                                                           
  23110.                                                                                 
  23111. #define  OPEN_TEXT_FILE_FOR_WRITE(F)  \                                         
  23112.          afopen((F),"w","seq","recfm=v,lrecl=255,blksize=6233")                 
  23113.                                                                                 
  23114. #define  OPEN_TEXT_FILE_FOR_APPEND(F)  \                                        
  23115.          afopen((F),"a","seq","recfm=v,lrecl=255,blksize=6233")                 
  23116.                                                                                 
  23117. #define  OPEN_TEXT_FILE_FOR_WRITE_OR_APPEND(F,B)  \                             
  23118.          afopen((F),(B)?"a":"w","seq","recfm=v,lrecl=255,blksize=6233")         
  23119.                                                                                 
  23120. #endif                                                                          
  23121.                                                                                 
  23122.                                                                                 
  23123. #define do_newsgroup_by_name(N,G)    NNMdng(N,NULL,G)                           
  23124. #define do_newsgroup_by_address(N,G) NNMdng(N,G,NULL)                           
  23125.                                                                                 
  23126. /****** Procedure and function declarations. *************************/         
  23127.                                                                                 
  23128. extern struct newsgroup   *NNMaddng(struct nncb *, char *);                     
  23129. extern void                NNMadjua(struct nncb *,                              
  23130.                                     struct newsgroup *, int, int, int);         
  23131. extern Bool                NNMallav(struct nncb *, struct newsgroup *);         
  23132. extern Bool                NNMalloc(char *, char *, enum data_set_type,         
  23133.                                                                   int);         
  23134. extern Bool                NNMauth (struct nncb *);                             
  23135. extern int                 NNMbatch(struct nncb *);                             
  23136. extern int                 NNMbrifr(char **, int *, int *, void *);             
  23137. extern int                 NNMbrifc(int *, void *);                             
  23138. extern void                NNMbtext(struct nncb *, struct texthdr *,            
  23139.                                                                FILE *);         
  23140. extern void                NNMclrng(struct nncb *);                             
  23141. extern void                NNMclrtx(struct nncb *,struct newsarticle *);        
  23142. extern void                NNMcnrf (struct nncb *, char *, Fool);               
  23143. extern Bool                NNMconn (struct nncb *);                             
  23144. extern char               *NNMcopy (struct nncb *, char *);                     
  23145. extern Bool                NNMdcan (struct nncb *,struct newsgroup *,           
  23146.                                                   struct newsarticle *);        
  23147. extern void                NNMdfail(int,__S99parms *);                          
  23148. extern void                NNMdisc (struct nncb *);                             
  23149. extern int                 NNMdispl(struct nncb *, char *);                     
  23150. extern Bool                NNMdlang(struct nncb *, enum list_option);           
  23151. extern void                NNMdmail(struct nncb *,struct newsgroup *,           
  23152.                                                   struct newsarticle *);        
  23153. extern enum display_retval NNMdmenu(struct nncb *, Bool (**)());                
  23154. extern struct newsgroup   *NNMdng  (struct nncb *,                              
  23155.                                            struct newsgroup *, char *);         
  23156. extern void                NNMdnntp(struct nncb *, char *);                     
  23157. extern void                NNMdoit (struct nncb *,                              
  23158.                                             struct newsarticle *, Fool);        
  23159. extern void                NNMdpost(struct nncb *,struct newsgroup *,           
  23160.                                                   struct newsarticle *);        
  23161. extern void                NNMdsopt(struct nncb *,char *);                      
  23162. extern void                NNMdump (struct nncb *,char *, char *, int);         
  23163. extern void                NNMesrvr(struct nncb *);                             
  23164. extern Bool                NNMestng(struct nncb *, char *);                     
  23165. extern void                NNMfreem(struct nncb *,char *,char *);               
  23166. extern FILE               *NNMgetds(struct nncb *,struct extraction *);         
  23167. extern void                NNMgetm (struct nncb *,char **,int,char *);          
  23168. extern Bool                NNMgsrvl(struct nncb *, char **);                    
  23169. extern void                NNMierr (struct nncb *);                             
  23170. extern int                 NNMiget (struct nncb *, char *);                     
  23171. extern void                NNMimsg (struct nncb *, char *);                     
  23172. extern void                NNMinit (struct nncb *);                             
  23173. extern Bool                NNMispf (struct nncb *, char *);                     
  23174. extern Bool                NNMivget(struct nncb *, char *, char *,int);         
  23175. extern Bool                NNMivput(struct nncb *, char *, char *,int);         
  23176. extern void                NNMmarr(struct nncb *, struct newsgroup *,           
  23177.                                                   struct newsarticle *);        
  23178. extern void                NNMmaru(struct nncb *, struct newsgroup *,           
  23179.                                                   struct newsarticle *);        
  23180. extern void                NNMnntp (struct nncb *);                             
  23181. extern void                NNMonrf (struct nncb *, char *);                     
  23182. extern struct textline    *NNMouttx(struct nncb *, char *,                      
  23183.                                                   struct newsarticle *);        
  23184. extern Bool                NNMpick (struct nncb *,struct newsarticle *);        
  23185. extern Bool                NNMpng  (struct nncb *,struct newsgroup *);          
  23186. extern void                NNMpnrl (struct nncb *,struct newsgroup *);          
  23187. extern void                NNMptx  (struct nncb *,struct newsarticle *);        
  23188. extern Bool                NNMqar  (struct nncb *,struct newsarticle *);        
  23189. extern void                NNMqng  (struct nncb *,struct newsgroup *);          
  23190. extern Bool                NNMraarh(struct nncb *,struct newsgroup *);          
  23191. extern Bool                NNMrarh (struct nncb *,struct newsgroup *,           
  23192.                                     struct newsarticle *, Fool,                 
  23193.                                     struct countdown *);                        
  23194. extern void                NNMrbfm (struct nncb *);                             
  23195. extern Bool                NNMrecon(struct nncb *);                             
  23196. extern void                NNMrperr(struct nncb *);                             
  23197. extern Bool                NNMsave (struct nncb *,char *);                      
  23198. extern Bool                NNMsockt(struct nncb *);                             
  23199. extern void                NNMsopt (struct nncb *, enum user_option);           
  23200. extern void                NNMsort (struct nncb *,struct newsgroup *);          
  23201. extern void                NNMssrvr(struct nncb *);                             
  23202. extern char               *NNMstrlc(char *, char *);                            
  23203. extern Bool                NNMsumat(char *, char *);                            
  23204. extern int                 NNMtso  (char *);                                    
  23205. extern Bool                NNMunalc(char *);                                    
  23206. extern void                NNMupdt (struct nncb *,struct countdown *,           
  23207.                                                   char *);                      
  23208. extern Bool                NNMvar  (struct nncb *,struct newsgroup *);          
  23209. extern Bool                NNMvng  (struct nncb *);                             
  23210. extern void                NNMvtx  (struct nncb *,struct newsgroup *,           
  23211.                                                   struct newsarticle *);        
  23212. extern Bool                NNMxartt(struct nncb *,struct newsgroup *);          
  23213. extern Bool                NNMxartx(struct nncb *,struct newsgroup *,           
  23214.                                                   enum data_set_type);          
  23215. extern Bool                NNMxlist(struct nncb *,char *);                      
  23216. extern Bool                NNMxtx  (struct nncb *,struct newsarticle *,         
  23217.                                                   Fool);                        
  23218.                                                                                 
  23219. #ifndef SUPPRESS_V_DECLARATION                                                  
  23220. extern void                NNMpmsg (struct nncb *,int,char *,char *,            
  23221.                                                                   ...);         
  23222. #endif                                                                          
  23223.                                                                                 
  23224. ./   ADD NAME=NNBATCH,SSI=01630036                                              
  23225.                                                                                 
  23226.  /********************************************************************/         
  23227.  /*                                                                  */         
  23228.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  23229.  /*                                                                  */         
  23230.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  23231.  /* including the implied warranties of merchantability and fitness, */         
  23232.  /* are expressly denied.                                            */         
  23233.  /*                                                                  */         
  23234.  /* Provided this copyright notice is included, this software may    */         
  23235.  /* be freely distributed and not offered for sale.                  */         
  23236.  /*                                                                  */         
  23237.  /* Changes or modifications may be made and used only by the maker  */         
  23238.  /* of same, and not further distributed.  Such modifications should */         
  23239.  /* be mailed to the author for consideration for addition to the    */         
  23240.  /* software and incorporation in subsequent releases.               */         
  23241.  /*                                                                  */         
  23242.  /********************************************************************/         
  23243.                                                                                 
  23244. /* ------------------ "nnbatch.h" include member ------------------- */         
  23245.                                                                                 
  23246. /* Include file for NNMVS batch mode operations. */                             
  23247.                                                                                 
  23248.                                                                                 
  23249. #define FIRST_ARTICLE_IN_RANGE             (-1)                                 
  23250. #define LAST_ARTICLE_IN_RANGE              (2147483647)                         
  23251.                                                                                 
  23252. #define MIN_RESERVED_WORD_LENGTH 2                                              
  23253. #define MAX_RESERVED_WORD_LENGTH 10                                             
  23254.                                                                                 
  23255. #define ANYTYPE     void *                                                      
  23256.                                                                                 
  23257. #define PEEK()      (NNMbgtok(np,bp,TOKEN_PEEK) ? &bp->nextok : NULL)           
  23258. #define EAT()       (void)NNMbgtok(np,bp,TOKEN_READ)                            
  23259.                                                                                 
  23260. #define SETA(X,Y)   NNMbvput(np,bp,(X),NUMBER_SYMTYPE,(ANYTYPE)(Y))             
  23261. #define SETB(X,Y)   NNMbvput(np,bp,(X),FLAG_SYMTYPE,  (ANYTYPE)(Y))             
  23262. #define SETC(X,Y)   NNMbvput(np,bp,(X),STRING_SYMTYPE,(ANYTYPE)(Y))             
  23263.                                                                                 
  23264. #define GETA(X)     (int)   NNMbvget(np,bp,(X),NUMBER_SYMTYPE)                  
  23265. #define GETB(X)     (Fool)  NNMbvget(np,bp,(X),FLAG_SYMTYPE)                    
  23266. #define GETC(X)     (char *)NNMbvget(np,bp,(X),STRING_SYMTYPE)                  
  23267.                                                                                 
  23268. typedef struct newscmd *(*CommandParser)   ();                                  
  23269. typedef void            (*CommandExecutor) ();                                  
  23270.                                                                                 
  23271. enum tokentype        {NO_TOKEN,                                                
  23272.                        EOL_TOKEN,                                               
  23273.                        EOF_TOKEN,                                               
  23274.                        AND_TOKEN,                                               
  23275.                        OR_TOKEN,                                                
  23276.                        NOT_TOKEN,                                               
  23277.                        GT_TOKEN,                                                
  23278.                        LT_TOKEN,                                                
  23279.                        EQ_TOKEN,                                                
  23280.                        NE_TOKEN,                                                
  23281.                        GE_TOKEN,                                                
  23282.                        LE_TOKEN,                                                
  23283.                        LPAR_TOKEN,                                              
  23284.                        RPAR_TOKEN,                                              
  23285.                        PLUS_TOKEN,                                              
  23286.                        MINUS_TOKEN,                                             
  23287.                        TIMES_TOKEN,                                             
  23288.                        OVER_TOKEN,                                              
  23289.                        SEMI_TOKEN,                                              
  23290.                        WORD_TOKEN,                                              
  23291.                        NUMBER_TOKEN,                                            
  23292.                        STRING_TOKEN,                                            
  23293.                        ERROR_TOKEN                                              
  23294.                       };                                                        
  23295.                                                                                 
  23296. enum tokenfunc        {                                                         
  23297.                        TOKEN_PEEK,                                              
  23298.                        TOKEN_READ,                                              
  23299.                        TOKEN_FLUSH                                              
  23300.                       };                                                        
  23301.                                                                                 
  23302. enum batchmode        {                                                         
  23303.                        INITIAL_MODE,                                            
  23304.                        PER_NEWSGROUP_MODE,                                      
  23305.                        PER_ARTICLE_MODE,                                        
  23306.                        TEXT_MODE,                                               
  23307.                        ERROR_MODE,                                              
  23308.                        ANY_MODE                                                 
  23309.                       };                                                        
  23310.                                                                                 
  23311. enum marking_mode     {                                                         
  23312.                        MARKING_READ,                                            
  23313.                        MARKING_UNREAD                                           
  23314.                       };                                                        
  23315.                                                                                 
  23316. enum extracting_mode  {                                                         
  23317.                        NO_EXTRACTING_MODE,                                      
  23318.                        EXTRACTING_ALL,                                          
  23319.                        EXTRACTING_READ,                                         
  23320.                        EXTRACTING_UNREAD                                        
  23321.                       };                                                        
  23322.                                                                                 
  23323. enum which_newsgroups {                                                         
  23324.                        NO_NEWSGROUPS,                                           
  23325.                        ALL_NEWSGROUPS,                                          
  23326.                        REGISTERED_NEWSGROUPS,                                   
  23327.                        UNREGISTERED_NEWSGROUPS,                                 
  23328.                        NAMED_NEWSGROUPS,                                        
  23329.                        MASKED_NEWSGROUPS                                        
  23330.                       };                                                        
  23331.                                                                                 
  23332. enum which_articles   {                                                         
  23333.                        NO_ARTICLES,                                             
  23334.                        ALL_ARTICLES,                                            
  23335.                        READ_ARTICLES,                                           
  23336.                        UNREAD_ARTICLES,                                         
  23337.                        RANGED_ARTICLES                                          
  23338.                       };                                                        
  23339.                                                                                 
  23340. enum symtype          {                                                         
  23341.                        NO_SYMTYPE,                                              
  23342.                        STRING_SYMTYPE,                                          
  23343.                        NUMBER_SYMTYPE,                                          
  23344.                        FLAG_SYMTYPE                                             
  23345.                       };                                                        
  23346.                                                                                 
  23347. /*-------------------------------------------------------------------*          
  23348.  * Define structures to handle expressions computed at run time.                
  23349.  *-------------------------------------------------------------------*/         
  23350.                                                                                 
  23351. #include "nnptree.h"   /* Grammar to handle general expressions */              
  23352.                                                                                 
  23353. /*-------------------------------------------------------------------*          
  23354.  * newsgroup_crit: defines criteria for selecting newsgroups.                   
  23355.  *                 Corresponds to xxx in:                                       
  23356.  *                   FOR xxx WHEN (yyy) DO zzz                                  
  23357.  *                 in top-level mode.                                           
  23358.  *-------------------------------------------------------------------*/         
  23359.                                                                                 
  23360. struct newsgroup_crit {                                                         
  23361.                        enum which_newsgroups     which;                         
  23362.                        struct ptree             *groups;                        
  23363.                       };                                                        
  23364.                                                                                 
  23365. /*-------------------------------------------------------------------*          
  23366.  * article_crit: defines criteria for selecting articles.                       
  23367.  *               Corresponds to xxx in:                                         
  23368.  *                 FOR xxx WHEN (yyy) DO zzz                                    
  23369.  *               in per-newsgroup mode.                                         
  23370.  *-------------------------------------------------------------------*/         
  23371.                                                                                 
  23372. struct article_crit {                                                           
  23373.                        enum which_articles       which;                         
  23374.                        struct ptree             *first;                         
  23375.                        struct ptree             *last;                          
  23376.                       };                                                        
  23377.                                                                                 
  23378. /*-------------------------------------------------------------------*          
  23379.  * for_newsgroups: defines what to do for each newsgroup and which              
  23380.  *                 newsgroups were selected.  Corresponds to:                   
  23381.  *                   FOR xxx WHEN (yyy) DO zzz                                  
  23382.  *                 in top-level mode.                                           
  23383.  *-------------------------------------------------------------------*/         
  23384.                                                                                 
  23385. struct for_newsgroups {                                                         
  23386.                        struct ptree             *filter;                        
  23387.                        struct newsgroup_crit     crit;                          
  23388.                        struct cmdtree           *treep;                         
  23389.                       };                                                        
  23390.                                                                                 
  23391. /*-------------------------------------------------------------------*          
  23392.  * for_articles:   defines what to do for each article and which                
  23393.  *                 articles were selected.  Corresponds to:                     
  23394.  *                   FOR xxx WHEN (yyy) DO zzz                                  
  23395.  *                 in per-newsgroup mode.                                       
  23396.  *-------------------------------------------------------------------*/         
  23397.                                                                                 
  23398. struct for_articles   {                                                         
  23399.                        struct ptree             *filter;                        
  23400.                        struct article_crit       crit;                          
  23401.                        struct cmdtree           *treep;                         
  23402.                       };                                                        
  23403.                                                                                 
  23404. /*-------------------------------------------------------------------*          
  23405.  * OK, here are defined the kinds of commands.                                  
  23406.  *-------------------------------------------------------------------*/         
  23407.                                                                                 
  23408. struct initial_mode_cmd        {                                                
  23409.                                 struct for_newsgroups       fors;               
  23410.                                };                                               
  23411.                                                                                 
  23412. struct per_newsgroup_mode_cmd  {                                                
  23413.                                 struct for_articles         fors;               
  23414.                                };                                               
  23415.                                                                                 
  23416. struct if_cmd                  {                                                
  23417.                                 struct ptree               *condition;          
  23418.                                 struct cmdtree             *thencmds;           
  23419.                                 struct cmdtree             *elsecmds;           
  23420.                                };                                               
  23421.                                                                                 
  23422. struct set_cmd                 {                                                
  23423.                                 struct ptree               *ptreep;             
  23424.                                 char *                      set_symbol;         
  23425.                                 enum symtype                set_type;           
  23426.                                };                                               
  23427.                                                                                 
  23428. struct mark_cmd                {                                                
  23429.                                 enum marking_mode           marking;            
  23430.                                };                                               
  23431.                                                                                 
  23432. struct extract_cmd             {                                                
  23433.                                 enum extracting_mode        extracting;         
  23434.                                };                                               
  23435.                                                                                 
  23436. struct miscellaneous_cmd       {                                                
  23437.                                 struct ptree               *ptreep;             
  23438.                                };                                               
  23439.                                                                                 
  23440. union some_mode_cmd   {                                                         
  23441.                        struct initial_mode_cmd       icmd;                      
  23442.                        struct per_newsgroup_mode_cmd ncmd;                      
  23443.                        struct if_cmd                 fcmd;                      
  23444.                        struct set_cmd                scmd;                      
  23445.                        struct mark_cmd               rcmd;                      
  23446.                        struct extract_cmd            xcmd;                      
  23447.                        struct miscellaneous_cmd      mcmd;                      
  23448.                       };                                                        
  23449.                                                                                 
  23450. /*-------------------------------------------------------------------*          
  23451.  * newscmd:   defines format of operations to perform on something.             
  23452.  *-------------------------------------------------------------------*/         
  23453.                                                                                 
  23454. struct newscmd        {                                                         
  23455.                        enum batchmode            mode;                          
  23456.                        CommandExecutor           proc;                          
  23457.                        union some_mode_cmd       cmd;                           
  23458.                       };                                                        
  23459.                                                                                 
  23460. struct cmdtree        {                                                         
  23461.                        struct cmdtree *next;                                    
  23462.                        struct newscmd *cmd;                                     
  23463.                       };                                                        
  23464.                                                                                 
  23465. #define MAX_SYMBOL_LENGTH      16                                               
  23466.                                                                                 
  23467. /*-------------------------------------------------------------------*          
  23468.  * symtab:    defines symbol table that holds values of variables.              
  23469.  *            The complete symbol table is a classic binary tree of             
  23470.  *            symtab structs.                                                   
  23471.  *                                                                              
  23472.  * To allocate, take length of variable value string,                           
  23473.  * then add that to offsetof(struct symtab,symval) to get total.                
  23474.  *-------------------------------------------------------------------*/         
  23475.                                                                                 
  23476. struct symtab {                                                                 
  23477.                char            symvar[MAX_SYMBOL_LENGTH];                       
  23478.                struct symtab  *left;                                            
  23479.                struct symtab  *right;                                           
  23480.                enum symtype    type;                                            
  23481.                int             symnum;                                          
  23482.                int             vallen;                                          
  23483.                char            symval[1];      /* dummy for alloc */            
  23484.               };                                                                
  23485.                                                                                 
  23486. struct token {                                                                  
  23487.               enum tokentype   type;                                            
  23488.               char             string [260];                                    
  23489.               int              number;                                          
  23490.              };                                                                 
  23491.                                                                                 
  23492. struct batch {                                                                  
  23493.               struct cmdtree     *treetop;                                      
  23494.               struct cmdtree     *treebottom;                                   
  23495.               struct symtab      *symtabp;                                      
  23496.               struct newsgroup   *gp;                                           
  23497.               struct newsarticle *ap;                                           
  23498.               struct newscmd     *ifcmd;                                        
  23499.               char               *inchar;                                       
  23500.               char               *reserved_words;                               
  23501.               char               *outfilename;                                  
  23502.               FILE               *outfp;                                        
  23503.               int                 input_errors;                                 
  23504.               int                 request_errors;                               
  23505.               enum batchmode      mode;                                         
  23506.               CommandParser       endproc;                                      
  23507.               Bool                syntax_error;                                 
  23508.               Bool                runtime_error;                                
  23509.               Bool                eof;                                          
  23510.               Bool                quit;                                         
  23511.               Bool                stop_at_newline;                              
  23512.               Bool                tokens_read;                                  
  23513.               Bool                newsgroups_retrieved;                         
  23514.               jmp_buf             jump;                                         
  23515.               struct token        curtok;                                       
  23516.               struct token        nextok;                                       
  23517.               char                inline          [260];                        
  23518.               char                extractds        [81];                        
  23519.               char                extractds_part1  [81];                        
  23520.               char                extractds_part2  [81];                        
  23521.               char                extractds_member [81];                        
  23522.               enum data_set_type  extractds_mode;                               
  23523.               Bool                exactcase;                                    
  23524.              };                                                                 
  23525.                                                                                 
  23526. extern ANYTYPE         NNMbbexp(struct nncb *, struct batch *,                  
  23527.                                           struct ptree *,enum symtype);         
  23528. extern Bool            NNMbconn(struct nncb *, struct batch *);                 
  23529. extern struct symtab  *NNMbdecl(struct nncb *, struct batch *, char *,          
  23530.                                                 enum symtype, ANYTYPE);         
  23531. extern void            NNMbflus(struct nncb *, struct batch *);                 
  23532. extern CommandParser   NNMbgcmd(struct nncb *, struct batch *);                 
  23533. extern struct cmdtree *NNMbgdo (struct nncb *, struct batch *,                  
  23534.                                                        enum batchmode);         
  23535. extern struct ptree   *NNMbgexp(struct nncb *, struct batch *,                  
  23536.                                                          enum symtype);         
  23537. extern Bool            NNMbgtok(struct nncb *, struct batch *,                  
  23538.                                                        enum tokenfunc);         
  23539. extern FILE           *NNMbsout(struct nncb *, struct batch *);                 
  23540. extern void            NNMbsynt(struct nncb *, struct batch *,                  
  23541.                                                   char *, int, char *);         
  23542. extern void            NNMbtras(struct nncb *, struct batch *, char *);         
  23543. extern ANYTYPE         NNMbvget(struct nncb *, struct batch *, char *,          
  23544.                                                          enum symtype);         
  23545. extern void            NNMbvput(struct nncb *, struct batch *, char *,          
  23546.                                                 enum symtype, ANYTYPE);         
  23547. extern void            NNMbxfar (struct nncb *, struct batch *,                 
  23548.                                                       struct newscmd *);        
  23549. extern void            NNMbxfng (struct nncb *, struct batch *,                 
  23550.                                                       struct newscmd *);        
  23551.                                                                                 
  23552. ./   ADD NAME=NNPTREE,SSI=011E0000                                              
  23553.                                                                                 
  23554.  /********************************************************************/         
  23555.  /*                                                                  */         
  23556.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  23557.  /*                                                                  */         
  23558.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  23559.  /* including the implied warranties of merchantability and fitness, */         
  23560.  /* are expressly denied.                                            */         
  23561.  /*                                                                  */         
  23562.  /* Provided this copyright notice is included, this software may    */         
  23563.  /* be freely distributed and not offered for sale.                  */         
  23564.  /*                                                                  */         
  23565.  /* Changes or modifications may be made and used only by the maker  */         
  23566.  /* of same, and not further distributed.  Such modifications should */         
  23567.  /* be mailed to the author for consideration for addition to the    */         
  23568.  /* software and incorporation in subsequent releases.               */         
  23569.  /*                                                                  */         
  23570.  /********************************************************************/         
  23571.                                                                                 
  23572. /* ----------------- "nnptree.h" include member -------------------- */         
  23573.                                                                                 
  23574. #define ALLOC(X,Y)   GETMAIN(X,struct Y,1,#Y);\                                 
  23575.                      if (!(X)) longjmp(bp->jump,ERROR_GETMAIN_FAILURE)          
  23576. #define ERR(X)       (NNMbsynt(np,bp,bp->curtok.string,0,X),\                   
  23577.                       longjmp(bp->jump,ERROR_BAD_EXPRESSION))                   
  23578. #define LOSE         longjmp(bp->jump,ERROR_SCAN_ERROR)                         
  23579.                                                                                 
  23580. #define ERROR_NONE              0                                               
  23581. #define ERROR_TYPE_MISMATCH     1                                               
  23582. #define ERROR_ZERODIVIDE        2                                               
  23583. #define ERROR_GETMAIN_FAILURE   3                                               
  23584. #define ERROR_BAD_EXPRESSION    4                                               
  23585. #define ERROR_SCAN_ERROR        5                                               
  23586.                                                                                 
  23587. /*-------------------------------------------------------------------*          
  23588.  * ptree: defines structure of expressions used by various commands,            
  23589.  * including SET, PUT and NNTP.  When these commands are parsed,                
  23590.  * a ptree structure is built to be interpreted when the command is             
  23591.  * executed.  The structure represents one of the following:                    
  23592.  *                                                                              
  23593.  * - a string expression (concatenated strings or string vars)                  
  23594.  * - a numeric expression (number, number var or arithmetic expr)               
  23595.  * - a flag expression (flag, flag var or logical expr)                         
  23596.  *                                                                              
  23597.  *-------------------------------------------------------------------*/         
  23598.                                                                                 
  23599. /*-------------------------------------------------------------------*          
  23600.  * treetype: type of an expression tree.                                        
  23601.  *-------------------------------------------------------------------*/         
  23602.                                                                                 
  23603. enum treetype   {                                                               
  23604.                  NO_TREETYPE,                                                   
  23605.                  STRING_TREETYPE,                                               
  23606.                  NUMBER_TREETYPE,                                               
  23607.                  FLAG_TREETYPE                                                  
  23608.                 };                                                              
  23609.                                                                                 
  23610. /*-------------------------------------------------------------------*          
  23611.  * rhstype:  type of an expression subtree, based on the RHS of a               
  23612.  *           production.  Defines the structure of the components               
  23613.  *           that make up this subtree.  Note that the types are                
  23614.  *           meaningful only within a given production (LHS) type.              
  23615.  *-------------------------------------------------------------------*/         
  23616.                                                                                 
  23617. enum rhstype    {                                                               
  23618.                  NO_RHSTYPE,                                                    
  23619.                  RHSTYPE_A,                                                     
  23620.                  RHSTYPE_B,                                                     
  23621.                  RHSTYPE_C,                                                     
  23622.                  RHSTYPE_D,                                                     
  23623.                  RHSTYPE_E                                                      
  23624.                 };                                                              
  23625.                                                                                 
  23626. /*-------------------------------------------------------------------*          
  23627.  * optype:  type of an operator                                                 
  23628.  *-------------------------------------------------------------------*/         
  23629.                                                                                 
  23630. enum optype     {                                                               
  23631.                  NO_OP,                                                         
  23632.                  AND_OP,                                                        
  23633.                  OR_OP,                                                         
  23634.                  NOT_OP,                                                        
  23635.                  IN_OP,                                                         
  23636.                  EQ_OP,                                                         
  23637.                  NE_OP,                                                         
  23638.                  GT_OP,                                                         
  23639.                  LT_OP,                                                         
  23640.                  GE_OP,                                                         
  23641.                  LE_OP,                                                         
  23642.                  ADD_OP,                                                        
  23643.                  SUB_OP,                                                        
  23644.                  MUL_OP,                                                        
  23645.                  DIV_OP                                                         
  23646.                 };                                                              
  23647.                                                                                 
  23648. /*-------------------------------------------------------------------*          
  23649.  * These types correspond to production LHS's.                                  
  23650.  *-------------------------------------------------------------------*/         
  23651.                                                                                 
  23652. typedef struct exp        *       Exp;                                          
  23653. typedef struct choice     *       Choice;                                       
  23654. typedef struct relation   *       Relation;                                     
  23655. typedef struct value      *       Value;                                        
  23656. typedef struct quantity   *       Quantity;                                     
  23657. typedef struct term       *       Term;                                         
  23658. typedef struct factor     *       Factor;                                       
  23659. typedef struct unop       *       Unop;                                         
  23660. typedef struct addop      *       Addop;                                        
  23661. typedef struct mulop      *       Mulop;                                        
  23662. typedef struct logop      *       Logop;                                        
  23663. typedef struct relop      *       Relop;                                        
  23664. typedef struct constant   *       Constant;                                     
  23665. typedef struct variable   *       Variable;                                     
  23666. typedef struct number     *       Number;                                       
  23667. typedef struct string     *       String;                                       
  23668. typedef struct flag       *       Flag;                                         
  23669.                                                                                 
  23670. /*-------------------------------------------------------------------*          
  23671.  * The following define the top-down LR(1) grammar.                             
  23672.  *-------------------------------------------------------------------*/         
  23673.                                                                                 
  23674. struct exp      {                                                               
  23675.                  enum rhstype           r;                                      
  23676.                  enum symtype           s;                                      
  23677.                  union {                                                        
  23678.                         struct {                                                
  23679.                                 Choice          choice1;                        
  23680.                                }        a;                                      
  23681.                         struct {                                                
  23682.                                 /* "IF" */                                      
  23683.                                 Exp             exp1;                           
  23684.                                 /* "THEN" */                                    
  23685.                                 Exp             exp2;                           
  23686.                                 /* "ELSE" */                                    
  23687.                                 Exp             exp3;                           
  23688.                                }        b;                                      
  23689.                        }                u;                                      
  23690.                 };                                                              
  23691.                                                                                 
  23692. struct choice   {                                                               
  23693.                  enum rhstype           r;                                      
  23694.                  enum symtype           s;                                      
  23695.                  union {                                                        
  23696.                         struct {                                                
  23697.                                 Relation        relation1;                      
  23698.                                }        a;                                      
  23699.                         struct {                                                
  23700.                                 Choice          choice1;                        
  23701.                                 Logop           logop2;                         
  23702.                                 Relation        relation3;                      
  23703.                                }        b;                                      
  23704.                        }                u;                                      
  23705.                 };                                                              
  23706.                                                                                 
  23707. struct relation {                                                               
  23708.                  enum rhstype           r;                                      
  23709.                  enum symtype           s;                                      
  23710.                  union {                                                        
  23711.                         struct {                                                
  23712.                                 Value           value1;                         
  23713.                                }        a;                                      
  23714.                         struct {                                                
  23715.                                 Value           value1;                         
  23716.                                 Relop           relop2;                         
  23717.                                 Value           value3;                         
  23718.                                }        b;                                      
  23719.                        }                u;                                      
  23720.                 };                                                              
  23721.                                                                                 
  23722. struct value    {                                                               
  23723.                  enum rhstype           r;                                      
  23724.                  enum symtype           s;                                      
  23725.                  union {                                                        
  23726.                         struct {                                                
  23727.                                 Quantity        quantity1;                      
  23728.                                }        a;                                      
  23729.                         struct {                                                
  23730.                                 Value           value1;                         
  23731.                                 Quantity        quantity2;                      
  23732.                                }        b;                                      
  23733.                        }                u;                                      
  23734.                 };                                                              
  23735.                                                                                 
  23736. struct quantity {                                                               
  23737.                  enum rhstype           r;                                      
  23738.                  enum symtype           s;                                      
  23739.                  union {                                                        
  23740.                         struct {                                                
  23741.                                 Term            term1;                          
  23742.                                }        a;                                      
  23743.                         struct {                                                
  23744.                                 Quantity        quantity1;                      
  23745.                                 Addop           addop2;                         
  23746.                                 Term            term3;                          
  23747.                                }        b;                                      
  23748.                        }                u;                                      
  23749.                 };                                                              
  23750.                                                                                 
  23751. struct term     {                                                               
  23752.                  enum rhstype           r;                                      
  23753.                  enum symtype           s;                                      
  23754.                  union {                                                        
  23755.                         struct {                                                
  23756.                                 Factor          factor1;                        
  23757.                                }        a;                                      
  23758.                         struct {                                                
  23759.                                 Term            term1;                          
  23760.                                 Mulop           mulop2;                         
  23761.                                 Factor          factor3;                        
  23762.                                }        b;                                      
  23763.                        }                u;                                      
  23764.                 };                                                              
  23765.                                                                                 
  23766. struct factor   {                                                               
  23767.                  enum rhstype           r;                                      
  23768.                  enum symtype           s;                                      
  23769.                  union {                                                        
  23770.                         struct {                                                
  23771.                                 Constant        constant1;                      
  23772.                                }        a;                                      
  23773.                         struct {                                                
  23774.                                 Variable        variable1;                      
  23775.                                }        b;                                      
  23776.                         struct {                                                
  23777.                                 Unop            unop1;                          
  23778.                                 Factor          factor2;                        
  23779.                                }        c;                                      
  23780.                         struct {                                                
  23781.                                 /* "(" */                                       
  23782.                                 Exp             exp1;                           
  23783.                                 /* ")" */                                       
  23784.                                }        d;                                      
  23785.                        }                u;                                      
  23786.                 };                                                              
  23787.                                                                                 
  23788. struct constant {                                                               
  23789.                  enum rhstype           r;                                      
  23790.                  enum symtype           s;                                      
  23791.                  union {                                                        
  23792.                         struct {                                                
  23793.                                 Number          number1;                        
  23794.                                }        a;                                      
  23795.                         struct {                                                
  23796.                                 String          string1;                        
  23797.                                }        b;                                      
  23798.                         struct {                                                
  23799.                                 Flag            flag1;                          
  23800.                                }        c;                                      
  23801.                        }                u;                                      
  23802.                 };                                                              
  23803.                                                                                 
  23804. struct unop     {                                                               
  23805.                  enum optype            op1;    /* + - ! ^ */                   
  23806.                 };                                                              
  23807.                                                                                 
  23808. struct addop    {                                                               
  23809.                  enum optype            op1;    /* + - */                       
  23810.                 };                                                              
  23811.                                                                                 
  23812. struct mulop    {                                                               
  23813.                  enum optype            op1;    /* * / */                       
  23814.                 };                                                              
  23815.                                                                                 
  23816. struct logop    {                                                               
  23817.                  enum optype            op1;    /* AND OR */                    
  23818.                 };                                                              
  23819.                                                                                 
  23820. struct relop    {                                                               
  23821.                  enum optype            op1;    /* EQ GT LE NE IN... */         
  23822.                 };                                                              
  23823.                                                                                 
  23824. struct variable {                                                               
  23825.                  enum symtype           s;                                      
  23826.                  char *                 variable1;                              
  23827.                 };                                                              
  23828.                                                                                 
  23829. struct number   {                                                               
  23830.                  enum symtype           s;                                      
  23831.                  int                    number1;                                
  23832.                 };                                                              
  23833.                                                                                 
  23834. struct string   {                                                               
  23835.                  enum symtype           s;                                      
  23836.                  char                  *string1;                                
  23837.                 };                                                              
  23838.                                                                                 
  23839. struct flag     {                                                               
  23840.                  enum symtype           s;                                      
  23841.                  Fool                   flag1;  /* ON OFF TRUE FALSE */         
  23842.                 };                                                              
  23843.                                                                                 
  23844. /*-------------------------------------------------------------------*          
  23845.  * thing: describes entity to be returned from a ptree at run time              
  23846.  *-------------------------------------------------------------------*/         
  23847.                                                                                 
  23848. struct thing    {                                                               
  23849.                  ANYTYPE                val;    /* char *, int, Fool */         
  23850.                  enum symtype           typ;    /* string/number/flag*/         
  23851.                 };                                                              
  23852.                                                                                 
  23853. /*-------------------------------------------------------------------*          
  23854.  * ptree: expression tree.  Root of string/number/flag expression               
  23855.  *-------------------------------------------------------------------*/         
  23856.                                                                                 
  23857. struct ptree    {                                                               
  23858.                  enum symtype           type;   /* string/number/flag*/         
  23859.                  Exp                    exp1;   /* actual expression */         
  23860.                 };                                                              
  23861.                                                                                 
  23862. ./   ADD NAME=NNSASC,SSI=01030021                                               
  23863.                                                                                 
  23864.  /********************************************************************/         
  23865.  /*                                                                  */         
  23866.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  23867.  /*                                                                  */         
  23868.  /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.          */         
  23869.  /*                                                                  */         
  23870.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  23871.  /* including the implied warranties of merchantability and fitness, */         
  23872.  /* are expressly denied.                                            */         
  23873.  /*                                                                  */         
  23874.  /* Provided this copyright notice is included, this software may    */         
  23875.  /* be freely distributed and not offered for sale.                  */         
  23876.  /*                                                                  */         
  23877.  /* Changes or modifications may be made and used only by the maker  */         
  23878.  /* of same, and not further distributed.  Such modifications should */         
  23879.  /* be mailed to the author for consideration for addition to the    */         
  23880.  /* software and incorporation in subsequent releases.               */         
  23881.  /*                                                                  */         
  23882.  /********************************************************************/         
  23883.                                                                                 
  23884. /* ------------------- "nnsasc.h" include member ------------------- */         
  23885.                                                                                 
  23886. #ifdef SASC                                                                     
  23887.                                                                                 
  23888. #define I370                                                                    
  23889.                                                                                 
  23890. #include <dynam.h>                                                              
  23891.                                                                                 
  23892. #define FETCH                                                                   
  23893.                                                                                 
  23894.  __inline void (*fetch( const char *modname ))()                                
  23895.  {                                                                              
  23896.    void (*fpp)();                                                               
  23897.                                                                                 
  23898.    loadm( modname, &fpp );                                                      
  23899.    return( fpp );                                                               
  23900.  }                                                                              
  23901.                                                                                 
  23902.  __inline int (*release( void (*fpp)() ))                                       
  23903.  {                                                                              
  23904.    unloadm( fpp );                                                              
  23905.    return( 0 );                                                                 
  23906.  }                                                                              
  23907.                                                                                 
  23908.                                                                                 
  23909. #ifndef __SVC99                                                                 
  23910.                                                                                 
  23911.   #define __SVC99  1                                                            
  23912.                                                                                 
  23913.   #include <code.h>                                                             
  23914.                                                                                 
  23915.   struct __S99struc                                                             
  23916.     {                                                                           
  23917.       unsigned char   __S99RBLN;  /* length of request block..20      */        
  23918.       unsigned char   __S99VERB;  /* verb code                        */        
  23919.       unsigned short  __S99FLAG1; /* FLAGS1 field of SVC99 Req Block  */        
  23920.       unsigned short  __S99ERROR; /* error code field                 */        
  23921.       unsigned short  __S99INFO;  /* information reason code          */        
  23922.       void           *__S99TXTPP; /* address of text unit pointer list*/        
  23923.       int             __reserved; /* reserved..will always be 0       */        
  23924.       unsigned int    __S99FLAG2; /* FLAGS2 field..can only be filled */        
  23925.                                   /* in by APF authorized programs    */        
  23926.     };                                                                          
  23927.                                                                                 
  23928.   typedef struct __S99struc __S99parms;                                         
  23929.                                                                                 
  23930.   __inline int svc99(__S99parms* svc99parmlist)                                 
  23931.     { return( (_ldregs(R1, &svc99parmlist),                                     
  23932.                _code(0, 0x0a63),                                                
  23933.                _stregs(R15) ) );                                                
  23934.     }                                                                           
  23935.                                                                                 
  23936. #endif                                                                          
  23937.                                                                                 
  23938. #define FALSE 0                                                                 
  23939. #define TRUE  1                                                                 
  23940.                                                                                 
  23941. #include <lcio.h>                                                               
  23942.                                                                                 
  23943. #define  MAXHOSTNAMELEN     64                                                  
  23944.                                                                                 
  23945. #define  __ctest(X)  fprintf(stderr,\                                           
  23946.                      "NNMVS: CTEST is not supported by this compiler.")         
  23947.                                                                                 
  23948. #endif                                                                          
  23949.                                                                                 
  23950. ./   ADD NAME=NNUSER,SSI=010D0025                                               
  23951.                                                                                 
  23952.  /********************************************************************/         
  23953.  /*                                                                  */         
  23954.  /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992    */         
  23955.  /*                                                                  */         
  23956.  /* This software is provided on an "AS IS" basis.  All warranties,  */         
  23957.  /* including the implied warranties of merchantability and fitness, */         
  23958.  /* are expressly denied.                                            */         
  23959.  /*                                                                  */         
  23960.  /* Provided this copyright notice is included, this software may    */         
  23961.  /* be freely distributed and not offered for sale.                  */         
  23962.  /*                                                                  */         
  23963.  /* Changes or modifications may be made and used only by the maker  */         
  23964.  /* of same, and not further distributed.  Such modifications should */         
  23965.  /* be mailed to the author for consideration for addition to the    */         
  23966.  /* software and incorporation in subsequent releases.               */         
  23967.  /*                                                                  */         
  23968.  /********************************************************************/         
  23969.                                                                                 
  23970. /* ------------------- "nnuser.h" include member ------------------- */         
  23971.                                                                                 
  23972. /* Include file for locally customized values. */                               
  23973.                                                                                 
  23974. /* Define levels of C/370 and TCP/IP.  This controls support for                
  23975.  * fetching of non-C load modules and socket error reporting.                   
  23976.  */                                                                             
  23977.                                                                                 
  23978. /* #define  C370V1    /* define this if C/370 Version 1 */                      
  23979.    #define  C370V2    /* define this if C/370 Version 2 or higher */            
  23980. /* #define  SASC      /* define this if SAS/C compiler */                       
  23981.                                                                                 
  23982. /* #define  TCPIPV1   /* define this if TCP/IP Version 1 */                     
  23983.    #define  TCPIPV2   /* define this if TCP/IP Version 2 or higher */           
  23984.                                                                                 
  23985. /* Define the following defaults for your installation. */                      
  23986.                                                                                 
  23987. /*                                                                              
  23988.  * Specify the "user name" portion of the "Sender:" address generated           
  23989.  * by posting and mailing requests.                                             
  23990.  *                                                                              
  23991.  */                                                                             
  23992.                                                                                 
  23993. #define NNMVS_NAME  "NNMVS"                                                     
  23994.                                                                                 
  23995. /*                                                                              
  23996.  * Specify the name of the authorization file used to pass AUTHINFO             
  23997.  * requests to the server, if the server requires.  This file should            
  23998.  * be readable only by NNMVS if possible.  See the sample authorization         
  23999.  * file (AUTH) for the format.                                                  
  24000.  *                                                                              
  24001.  */                                                                             
  24002.                                                                                 
  24003. /* #define AUTHFILE    "SYS4.NNTP.SYS"  */                                      
  24004.    #undef  AUTHFILE                                                             
  24005.                                                                                 
  24006. /*                                                                              
  24007.  * Turn on for TCP-level debugging output (you probably don't want to           
  24008.  * unless your TCP/IP stuff is really broken and I can't help you).             
  24009.  */                                                                             
  24010.                                                                                 
  24011. /* #define DEBUG       */                                                       
  24012.    #undef  DEBUG                                                                
  24013.                                                                                 
  24014. ./ ENDUP                                                                        
  24015. ?!                                                                              
  24016. //PANELS   EXEC NNLOAD,TRK1='8',TO='PANELS'                                     
  24017. //SYSIN    DD DATA,DLM='?!'                                                     
  24018. ./   ADD NAME=COPYRITE,SSI=01000028                                             
  24019. /*                                                                   /*         
  24020. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24021. /*                                                                   /*         
  24022. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  24023. /*                                                                   /*         
  24024. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24025. /* including the implied warranties of merchantability and fitness,  /*         
  24026. /* are expressly denied.                                             /*         
  24027. /*                                                                   /*         
  24028. /* Provided this copyright notice is included, this software may     /*         
  24029. /* be freely distributed and not offered for sale.                   /*         
  24030. /*                                                                   /*         
  24031. /* Changes or modifications may be made and used only by the maker   /*         
  24032. /* of same, and not further distributed.  Such modifications should  /*         
  24033. /* be mailed to the author for consideration for addition to the     /*         
  24034. /* software and incorporation in subsequent releases.                /*         
  24035. /*                                                                   /*         
  24036. ./   ADD NAME=NNL,SSI=01010002                                                  
  24037. )ATTR                                                                           
  24038.  ~ TYPE(INPUT)  INTENS(HIGH) PAD('_')                                           
  24039.  # TYPE(INPUT)  INTENS(LOW)  CAPS(OFF)                                          
  24040.  $ TYPE(INPUT)  INTENS(LOW)  CAPS(ON)                                           
  24041. )BODY                                                                           
  24042. %---------------  NETNEWS SERVER SELECTION MENU  -------------------------------
  24043. %Command ===>_ZCMD                                            %Scroll ===>_AMT +
  24044. %                                                                               
  24045. +Line commands:    %D+(Delete) %I+(Insert) %R+(Replicate) %S+(Select)           
  24046. %                                                                               
  24047. %    Server                                       NEWSRC dsname                 
  24048. %    -------------------------------------------- ------------------------------
  24049. )MODEL                                                                          
  24050. %~Z%#SERVER                                      $NEWSRC                        
  24051. )INIT                                                                           
  24052.   .ZVARS = '(NNSEL)'                                                            
  24053.   &AMT = &ZSCML                                                                 
  24054. )PROC                                                                           
  24055.   IF (&ZCMD ^= &Z) .MSG = ISPZ001                                               
  24056.   &ZSCML = &AMT                                                                 
  24057.   VPUT (ZSCML) PROFILE                                                          
  24058. )END                                                                            
  24059.  /* Panel due to Leonard D. Woren <ldw@mvsa.usc.edu>. */                        
  24060. ./   ADD NAME=NNM,SSI=01200052                                                  
  24061. )ATTR                                                                           
  24062. /*                                                                   /*         
  24063. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24064. /*                                                                   /*         
  24065. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  24066. /*                                                                   /*         
  24067. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24068. /* including the implied warranties of merchantability and fitness,  /*         
  24069. /* are expressly denied.                                             /*         
  24070. /*                                                                   /*         
  24071. /* Provided this copyright notice is included, this software may     /*         
  24072. /* be freely distributed and not offered for sale.                   /*         
  24073. /*                                                                   /*         
  24074. /* Changes or modifications may be made and used only by the maker   /*         
  24075. /* of same, and not further distributed.  Such modifications should  /*         
  24076. /* be mailed to the author for consideration for addition to the     /*         
  24077. /* software and incorporation in subsequent releases.                /*         
  24078. /*                                                                   /*         
  24079.  ^ TYPE(INPUT) INTENS(HIGH) COLOR(GREEN) CAPS(OFF)                              
  24080.  ! TYPE(TEXT)  INTENS(HIGH) COLOR(RED)                                          
  24081. )BODY EXPAND(``)                                                                
  24082. %-`-`-  MVS Network News Viewer -`-`-                                           
  24083. %COMMAND ===>_ZCMD                                                              
  24084. +                                                                               
  24085. +Select one of the following options:                                           
  24086. +                                                                               
  24087. + %L+or%blank+   - List all newsgroups from server                              
  24088. + %N +NEWGROUPS  - List new newsgroups from server since last N or L            
  24089. + %A +ALL        - Select items from all newsgroups listed in NEWSRC file       
  24090. + %R +REGISTERED - Select items from registered newsgroups in NEWSRC file       
  24091. + %G +GROUP      - Go directly to the newsgroup named below                     
  24092. + %NNTP+         - Enter native NNTP protocol commands                          
  24093. + %OPTions+      - Specify NNMVS defaults                                       
  24094. + %X +EXIT       - Bye                                                          
  24095. +                                                                               
  24096. %Newsgroup name +(if option G selected)%===>^NNGROUPI                           
  24097. +                                                                               
  24098. %News server host name+(or IP address) %===>_NNSERVER                           
  24099. +                                                                               
  24100. %Name of NEWSRC data set               %===>_NNNEWSRF                           
  24101. +                                                                               
  24102. +Press!END+key to leave this menu.                                              
  24103. )INIT                                                                           
  24104.  .HELP = TNNM                                                                   
  24105.  IF (&NNCURSOR = &Z)                                                            
  24106.   IF (&NNSERVER = &Z)                                                           
  24107.    .CURSOR = NNSERVER                                                           
  24108.   ELSE                                                                          
  24109.    .CURSOR = ZCMD                                                               
  24110.  ELSE                                                                           
  24111.   .CURSOR = &NNCURSOR                                                           
  24112.  &ZCMD = &Z                                                                     
  24113.  IF (&NNREGNNG = &Z) &NNREGNNG = PROMPT                                         
  24114.  IF (&NNNEWSRF = &Z) &NNNEWSRF = NEWSRC                                         
  24115. )PROC                                                                           
  24116.  IF   (&NNGROUPI ^= &Z) VER(&ZCMD,NB)                                           
  24117.  IF   (&ZCMD = ' ')  &ZCMD = 'L'      /* remove if you hate BLANK */            
  24118.  &ZCMD = TRANS(&ZCMD A,A R,R L,L G,G N,N                                        
  24119.                      O,O OPT,O OPTIONS,O NNTP,P P,P X,X *,?)                    
  24120.  IF   (&ZCMD ^= 'X') VER (&NNSERVER,NB)                                         
  24121.  IF   (&ZCMD = 'G')  VER (&NNGROUPI,NB)                                         
  24122.  &NNREGNNG = TRUNC(&NNREGNNG,1)                                                 
  24123.  VER  (&NNREGNNG,NB,LIST,Y,N,P)                                                 
  24124.  VER  (&NNNEWSRF,NB,DSNAME)                                                     
  24125.  &TEMP1 = TRUNC(&NNNEWSRF,1)                                                    
  24126.  &TEMP2 = .TRAIL                                                                
  24127.  IF (&TEMP1 = '''')                                                             
  24128.   &NNNEWSRC = TRUNC(&TEMP2,'''')                                                
  24129.  ELSE                                                                           
  24130.   &NNNEWSRC = '&ZPREFIX..&NNNEWSRF'                                             
  24131.  VPUT (NNGROUPI NNSERVER NNREGNNG NNNEWSRF) PROFILE                             
  24132. )END                                                                            
  24133. ./   ADD NAME=NNMBROBF                                                          
  24134. )ATTR                                                                           
  24135. /*                                                                   */         
  24136. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     */         
  24137. /*                                                                   */         
  24138. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           */         
  24139. /*                                                                   */         
  24140. /* This software is provided on an "AS IS" basis.  All warranties,   */         
  24141. /* including the implied warranties of merchantability and fitness,  */         
  24142. /* are expressly denied.                                             */         
  24143. /*                                                                   */         
  24144. /* Provided this copyright notice is included, this software may     */         
  24145. /* be freely distributed and not offered for sale.                   */         
  24146. /*                                                                   */         
  24147. /* Changes or modifications may be made and used only by the maker   */         
  24148. /* of same, and not further distributed.  Such modifications should  */         
  24149. /* be mailed to the author for consideration for addition to the     */         
  24150. /* software and incorporation in subsequent releases.                */         
  24151. /*                                                                   */         
  24152.    _ TYPE(INPUT) CAPS(OFF) INTENS(HIGH) FORMAT(&MIXED)                          
  24153.    + TYPE(TEXT) INTENS(LOW)                                                     
  24154. )BODY  WIDTH(&ZWIDTH) EXPAND(//)                                                
  24155. %BROWSE ----------------------------------/-/----------------------------------+
  24156. %COMMAND ===>_ZCMD                        / /                 %SCROLL ===>_Z   +
  24157. )INIT                                                                           
  24158.   &TNNMTHR = 'NNMBROBF'                                                         
  24159.   .HELP = TNNMB1                                                                
  24160.   .ZVARS = 'ZSCBR'                                                              
  24161.   &MIXED = MIX             /* SET FORMAT MIX            */                      
  24162.   IF (&ZPDMIX = N)         /* IF EBCDIC MODE REQUESTED  */                      
  24163.     &MIXED = EBCDIC        /*  SET FORMAT EBCDIC        */                      
  24164. )END                                                                            
  24165. /* 5665-402 (C) COPYRIGHT IBM CORP 1980, 1989 */                                
  24166. ./   ADD NAME=NNMDAR,SSI=01070000                                               
  24167. )ATTR DEFAULT(%+\)                                                              
  24168. /*                                                                   /*         
  24169. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24170. /*                                                                   /*         
  24171. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24172. /* including the implied warranties of merchantability and fitness,  /*         
  24173. /* are expressly denied.                                             /*         
  24174. /*                                                                   /*         
  24175. /* Provided this copyright notice is included, this software may     /*         
  24176. /* be freely distributed and not offered for sale.                   /*         
  24177. /*                                                                   /*         
  24178. /* Changes or modifications may be made and used only by the maker   /*         
  24179. /* of same, and not further distributed.  Such modifications should  /*         
  24180. /* be mailed to the author for consideration for addition to the     /*         
  24181. /* software and incorporation in subsequent releases.                /*         
  24182. /*                                                                   /*         
  24183.  ~ TYPE(INPUT) INTENS(HIGH)  CAPS(OFF) JUST(LEFT)                               
  24184.  ^ TYPE(INPUT) INTENS(HIGH)  CAPS(OFF) JUST(LEFT)                               
  24185.  |  AREA(DYNAMIC) EXTEND(ON) SCROLL(ON)                                         
  24186.  01 TYPE(DATAOUT) INTENS(LOW)                                                   
  24187.  02 TYPE(DATAOUT) INTENS(HIGH)                                                  
  24188.  03 TYPE(DATAIN)  INTENS(LOW)                                                   
  24189.  04 TYPE(DATAIN)  INTENS(HIGH)                                                  
  24190.  05 TYPE(DATAOUT) COLOR(GREEN)                                                  
  24191.  06 TYPE(DATAOUT) COLOR(PINK)                                                   
  24192.  07 TYPE(DATAOUT) COLOR(RED)                                                    
  24193.  08 TYPE(DATAOUT) COLOR(TURQ)                                                   
  24194.  09 TYPE(DATAOUT) COLOR(YELLOW)                                                 
  24195.  0A TYPE(DATAIN)  COLOR(BLUE)                                                   
  24196.  0B TYPE(DATAIN)  COLOR(PINK)                                                   
  24197.  0C TYPE(DATAIN)  COLOR(TURQ)                                                   
  24198.  0D TYPE(DATAIN)  COLOR(WHITE)                                                  
  24199.  0E TYPE(DATAIN)  COLOR(YELLOW)                                                 
  24200. )BODY EXPAND(``)                                                                
  24201. %&NNTHEAD                                                                       
  24202. %COMMAND ===>~NNTCMD                                          %SCROLL ===>^NNTS+
  24203. +                                                                               
  24204. %Article: %S+select %E+extract %M+mark read%U+mark unread %Status     Date      
  24205.  _______________________________________________________________________________
  24206. |NNTDYNA                                                                       |
  24207. )INIT                                                                           
  24208.  .HELP = TNNM                                                                   
  24209.  IF (&NNTS = &Z) &NNTS = CSR                                                    
  24210. )PROC                                                                           
  24211.  &NNTLVL = LVLINE(NNTDYNA)                                                      
  24212.  VPUT (NNTS) PROFILE                                                            
  24213. )END                                                                            
  24214. ./   ADD NAME=NNMDBOGG,SSI=01050050                                             
  24215. )ATTR DEFAULT(%+_)                                                              
  24216. /*                                                                   /*         
  24217. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24218. /*                                                                   /*         
  24219. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24220. /* including the implied warranties of merchantability and fitness,  /*         
  24221. /* are expressly denied.                                             /*         
  24222. /*                                                                   /*         
  24223. /* Provided this copyright notice is included, this software may     /*         
  24224. /* be freely distributed and not offered for sale.                   /*         
  24225. /*                                                                   /*         
  24226. /* Changes or modifications may be made and used only by the maker   /*         
  24227. /* of same, and not further distributed.  Such modifications should  /*         
  24228. /* be mailed to the author for consideration for addition to the     /*         
  24229. /* software and incorporation in subsequent releases.                /*         
  24230. /*                                                                   /*         
  24231.  ^  TYPE(INPUT)  INTENS(HIGH) CAPS(ON) JUST(LEFT)                               
  24232.  |  AREA(DYNAMIC) EXTEND(ON) SCROLL(ON)                                         
  24233.  01 TYPE(DATAOUT) INTENS(LOW)                                                   
  24234.  02 TYPE(DATAOUT) INTENS(HIGH)                                                  
  24235.  03 TYPE(DATAIN)  INTENS(LOW)                                                   
  24236.  04 TYPE(DATAIN)  INTENS(HIGH)                                                  
  24237. )BODY EXPAND(``)                                                                
  24238. %-`-`- Unknown Newsgroups (found in NEWSRC but not by server) -`-`-             
  24239. %COMMAND ===>^ZCMD                                            %SCROLL ===>_AMT +
  24240.                                                                                 
  24241. +Groups displayed will be deleted from NEWSRC.  Scroll up/down to see all.      
  24242. +Type%K+to keep a group,%D+to delete. %&END+to accept. %QUIT+or%CANCEL+to abort.
  24243. -------------------------------------------------------------------------------+
  24244. |NNDYNA                                                                        |
  24245. )INIT                                                                           
  24246.  .HELP = TNNM                                                                   
  24247.  &END = PFK(END)                                                                
  24248.  IF (&AMT = &Z) &AMT = CSR                                                      
  24249.  IF (&NNDB1ST = &Z)                                                             
  24250.   &NNDB1ST = NO                                                                 
  24251.   .ALARM = YES                                                                  
  24252. )PROC                                                                           
  24253.  VER (&ZCMD,LIST,QUIT,CAN,CANCEL)                                               
  24254.  &NNLVL = LVLINE(NNDYNA)                                                        
  24255. )END                                                                            
  24256. ./   ADD NAME=NNMDNEWG,SSI=01080002                                             
  24257. )ATTR DEFAULT(%+_)                                                              
  24258. /*                                                                   /*         
  24259. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24260. /*                                                                   /*         
  24261. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24262. /* including the implied warranties of merchantability and fitness,  /*         
  24263. /* are expressly denied.                                             /*         
  24264. /*                                                                   /*         
  24265. /* Provided this copyright notice is included, this software may     /*         
  24266. /* be freely distributed and not offered for sale.                   /*         
  24267. /*                                                                   /*         
  24268. /* Changes or modifications may be made and used only by the maker   /*         
  24269. /* of same, and not further distributed.  Such modifications should  /*         
  24270. /* be mailed to the author for consideration for addition to the     /*         
  24271. /* software and incorporation in subsequent releases.                /*         
  24272. /*                                                                   /*         
  24273.  ^  TYPE(INPUT)  INTENS(HIGH) CAPS(ON) JUST(LEFT)                               
  24274.  |  AREA(DYNAMIC) EXTEND(ON) SCROLL(ON)                                         
  24275.  01 TYPE(DATAOUT) INTENS(LOW)                                                   
  24276.  02 TYPE(DATAOUT) INTENS(HIGH)                                                  
  24277.  03 TYPE(DATAIN)  INTENS(LOW)                                                   
  24278.  04 TYPE(DATAIN)  INTENS(HIGH)                                                  
  24279. )BODY EXPAND(``)                                                                
  24280. %-`-`- New Newsgroups -`-`-                                                     
  24281. %COMMAND ===>^ZCMD                                            %SCROLL ===>_AMT +
  24282.                                                                                 
  24283. +Type%R+to register a newsgroup; %D+to deregister. Scroll up/down to see all.   
  24284. +Registered group names highlighted. %&END+to accept. %QUIT+or%CANCEL+to abort. 
  24285. -------------------------------------------------------------------------------+
  24286. |NNDYNA                                                                        |
  24287. )INIT                                                                           
  24288.  .HELP = TNNM                                                                   
  24289.  &END = PFK(END)                                                                
  24290.  IF (&AMT = &Z) &AMT = CSR                                                      
  24291.  IF (&NNDN1ST = &Z)                                                             
  24292.   &NNDN1ST = NO                                                                 
  24293.   .ALARM = YES                                                                  
  24294. )PROC                                                                           
  24295.  VER (&ZCMD,LIST,QUIT,CAN,CANCEL)                                               
  24296.  &NNLVL = LVLINE(NNDYNA)                                                        
  24297. )END                                                                            
  24298. ./   ADD NAME=NNMDNG,SSI=01050001                                               
  24299. )ATTR                                                                           
  24300. /*                                                                   /*         
  24301. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24302. /*                                                                   /*         
  24303. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24304. /* including the implied warranties of merchantability and fitness,  /*         
  24305. /* are expressly denied.                                             /*         
  24306. /*                                                                   /*         
  24307. /* Provided this copyright notice is included, this software may     /*         
  24308. /* be freely distributed and not offered for sale.                   /*         
  24309. /*                                                                   /*         
  24310. /* Changes or modifications may be made and used only by the maker   /*         
  24311. /* of same, and not further distributed.  Such modifications should  /*         
  24312. /* be mailed to the author for consideration for addition to the     /*         
  24313. /* software and incorporation in subsequent releases.                /*         
  24314. /*                                                                   /*         
  24315.  ~ TYPE(INPUT) INTENS(HIGH)  CAPS(OFF) JUST(LEFT)                               
  24316.  ^ TYPE(INPUT) INTENS(HIGH)  CAPS(OFF) JUST(LEFT)                               
  24317.  ! TYPE(OUTPUT) INTENS(LOW)  CAPS(OFF) JUST(RIGHT) COLOR(YELLOW)                
  24318.  # TYPE(OUTPUT) INTENS(LOW)  CAPS(OFF) JUST(RIGHT) COLOR(BLUE)                  
  24319.  @ TYPE(OUTPUT) INTENS(HIGH) CAPS(OFF) JUST(RIGHT) COLOR(PINK)                  
  24320.  ? TYPE(OUTPUT) INTENS(LOW)  CAPS(OFF) JUST(LEFT)  COLOR(TURQ) PAD('.')         
  24321.  |  AREA(DYNAMIC) EXTEND(ON) SCROLL(ON)                                         
  24322.  \  AREA(DYNAMIC) EXTEND(OFF) SCROLL(OFF)                                       
  24323.  01 TYPE(DATAOUT) INTENS(LOW)                                                   
  24324.  02 TYPE(DATAOUT) INTENS(HIGH)                                                  
  24325.  03 TYPE(DATAIN)  INTENS(LOW)                                                   
  24326.  04 TYPE(DATAIN)  INTENS(HIGH)                                                  
  24327.  05 TYPE(DATAOUT) COLOR(GREEN)                                                  
  24328.  06 TYPE(DATAOUT) COLOR(PINK)                                                   
  24329.  07 TYPE(DATAOUT) COLOR(RED)                                                    
  24330.  08 TYPE(DATAOUT) COLOR(TURQ)                                                   
  24331.  09 TYPE(DATAOUT) COLOR(YELLOW)                                                 
  24332.  0A TYPE(DATAIN)  COLOR(BLUE)                                                   
  24333.  0B TYPE(DATAIN)  COLOR(PINK)                                                   
  24334.  0C TYPE(DATAIN)  COLOR(TURQ)                                                   
  24335.  0D TYPE(DATAIN)  COLOR(WHITE)                                                  
  24336.  0E TYPE(DATAIN)  COLOR(YELLOW)                                                 
  24337. )BODY EXPAND(``)                                                                
  24338. %&NNGHEAD                                                                       
  24339. %COMMAND ===>~NNGCMD                                          %SCROLL ===>^NNGS+
  24340. +                                                                               
  24341. \NNGLINE                                                                       \
  24342.  -------------------------------------------------------------------------------
  24343. |NNGDYNA                                                                       |
  24344. )INIT                                                                           
  24345.  .HELP = TNNM                                                                   
  24346.  IF (&NNGS = &Z) &NNGS = CSR                                                    
  24347. )PROC                                                                           
  24348.  &NNGLVL = LVLINE(NNGDYNA)                                                      
  24349.  VPUT (NNGS) PROFILE                                                            
  24350. )END                                                                            
  24351. ./   ADD NAME=NNMLADDG,SSI=01020000                                             
  24352. )ATTR                                                                           
  24353. /*                                                                   /*         
  24354. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24355. /*                                                                   /*         
  24356. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24357. /* including the implied warranties of merchantability and fitness,  /*         
  24358. /* are expressly denied.                                             /*         
  24359. /*                                                                   /*         
  24360. /* Provided this copyright notice is included, this software may     /*         
  24361. /* be freely distributed and not offered for sale.                   /*         
  24362. /*                                                                   /*         
  24363. /* Changes or modifications may be made and used only by the maker   /*         
  24364. /* of same, and not further distributed.  Such modifications should  /*         
  24365. /* be mailed to the author for consideration for addition to the     /*         
  24366. /* software and incorporation in subsequent releases.                /*         
  24367. /*                                                                   /*         
  24368.  @ TYPE(OUTPUT) INTENS(LOW)                                                     
  24369. )BODY EXPAND(``)                                                                
  24370. %-`-`-  MVS Network News Connection -`-`-                                       
  24371. +                                                                               
  24372. +                                                                               
  24373.          Adding newsgroup:                                                      
  24374. %        &NNLGROUP                                                              
  24375. +                                                                               
  24376.          (Estimated number of articles...&NNLCOUNT)                             
  24377. +        @NNDUMMY                                                               
  24378. +                                                                               
  24379.                                  % Please wait.                                 
  24380. +                                                                               
  24381. +                                                                               
  24382. )INIT                                                                           
  24383. )PROC                                                                           
  24384. )END                                                                            
  24385. ./   ADD NAME=NNMLADD2,SSI=01010017                                             
  24386. )ATTR DEFAULT(|+_)                                                              
  24387. /*                                                                   /*         
  24388. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24389. /*                                                                   /*         
  24390. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  24391. /*                                                                   /*         
  24392. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24393. /* including the implied warranties of merchantability and fitness,  /*         
  24394. /* are expressly denied.                                             /*         
  24395. /*                                                                   /*         
  24396. /* Provided this copyright notice is included, this software may     /*         
  24397. /* be freely distributed and not offered for sale.                   /*         
  24398. /*                                                                   /*         
  24399. /* Changes or modifications may be made and used only by the maker   /*         
  24400. /* of same, and not further distributed.  Such modifications should  /*         
  24401. /* be mailed to the author for consideration for addition to the     /*         
  24402. /* software and incorporation in subsequent releases.                /*         
  24403. /*                                                                   /*         
  24404.  ^ TYPE(DATAOUT) INTENS(HIGH) COLOR(TURQ) HILITE(REVERSE)                       
  24405.  / TYPE(DATAOUT) INTENS(HIGH) COLOR(TURQ)                                       
  24406.  * AREA(DYNAMIC)                                                                
  24407. )BODY EXPAND(``)                                                                
  24408. |-`-`-  MVS Network News Connection -`-`-                                       
  24409. +                                                                               
  24410.                                                                                 
  24411.          Now adding newsgroups                                                  
  24412.                                                                                 
  24413. +                                                                               
  24414.          Percentage of news groups processed:                                   
  24415.          ------------------------------------------------------------           
  24416.         *NNMBAR                                                     *|&NNMCOUNT 
  24417. +        ------------------------------------------------------------           
  24418.         0%                          50%                              100%       
  24419.                                                                                 
  24420.      This may take a long time, depending on the number of newsgroups.          
  24421.                                                                                 
  24422.                                                                                 
  24423. |                                  Please wait.                                 
  24424.                                                                                 
  24425. )INIT                                                                           
  24426. )PROC                                                                           
  24427. )END                                                                            
  24428. ./   ADD NAME=NNMLADD3,SSI=01000012                                             
  24429. )ATTR DEFAULT(|+_)                                                              
  24430. /*                                                                   /*         
  24431. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24432. /*                                                                   /*         
  24433. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  24434. /*                                                                   /*         
  24435. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24436. /* including the implied warranties of merchantability and fitness,  /*         
  24437. /* are expressly denied.                                             /*         
  24438. /*                                                                   /*         
  24439. /* Provided this copyright notice is included, this software may     /*         
  24440. /* be freely distributed and not offered for sale.                   /*         
  24441. /*                                                                   /*         
  24442. /* Changes or modifications may be made and used only by the maker   /*         
  24443. /* of same, and not further distributed.  Such modifications should  /*         
  24444. /* be mailed to the author for consideration for addition to the     /*         
  24445. /* software and incorporation in subsequent releases.                /*         
  24446. /*                                                                   /*         
  24447.  ^ TYPE(DATAOUT) INTENS(HIGH) COLOR(TURQ) HILITE(REVERSE)                       
  24448.  / TYPE(DATAOUT) INTENS(HIGH) COLOR(TURQ)                                       
  24449.  * AREA(DYNAMIC)                                                                
  24450. )BODY EXPAND(``)                                                                
  24451. |-`-`-  MVS Network News Connection -`-`-                                       
  24452. +                                                                               
  24453.                                                                                 
  24454.          Now adding newsgroup:                                                  
  24455.         |&NNLGROUP                                                              
  24456. +                                                                               
  24457.          Percentage of news groups processed:                                   
  24458.          ------------------------------------------------------------           
  24459.         *NNMBAR                                                     *|&NNMCOUNT 
  24460. +        ------------------------------------------------------------           
  24461.         0%                          50%                              100%       
  24462.                                                                                 
  24463.      This may take a long time, depending on the number of newsgroups.          
  24464.                                                                                 
  24465.                                                                                 
  24466. |                                  Please wait.                                 
  24467.                                                                                 
  24468. )INIT                                                                           
  24469. )PROC                                                                           
  24470. )END                                                                            
  24471. ./   ADD NAME=NNMLARTS,SSI=01030000                                             
  24472. )ATTR                                                                           
  24473. /*                                                                   /*         
  24474. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24475. /*                                                                   /*         
  24476. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24477. /* including the implied warranties of merchantability and fitness,  /*         
  24478. /* are expressly denied.                                             /*         
  24479. /*                                                                   /*         
  24480. /* Provided this copyright notice is included, this software may     /*         
  24481. /* be freely distributed and not offered for sale.                   /*         
  24482. /*                                                                   /*         
  24483. /* Changes or modifications may be made and used only by the maker   /*         
  24484. /* of same, and not further distributed.  Such modifications should  /*         
  24485. /* be mailed to the author for consideration for addition to the     /*         
  24486. /* software and incorporation in subsequent releases.                /*         
  24487. /*                                                                   /*         
  24488.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  24489.  @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)                                          
  24490.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  24491.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  24492.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  24493.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  24494.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  24495. )BODY EXPAND(``)                                                                
  24496. %-`-`-  MVS Network News Connection -`-`-                                       
  24497. +                                                                               
  24498. +                                                                               
  24499.          Now retrieving the titles of the articles in newsgroup:                
  24500. %        &NNGROUP                                                               
  24501. +                                                                               
  24502.      This may take a long time, depending on the number of articles.            
  24503. +                                                                               
  24504. +                                                                               
  24505.                                  % Please wait.                                 
  24506. +                                                                               
  24507. +                                                                               
  24508. )INIT                                                                           
  24509. )PROC                                                                           
  24510. )END                                                                            
  24511. ./   ADD NAME=NNMLART2,SSI=01020035                                             
  24512. )ATTR DEFAULT(|+_)                                                              
  24513. /*                                                                   /*         
  24514. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24515. /*                                                                   /*         
  24516. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  24517. /*                                                                   /*         
  24518. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24519. /* including the implied warranties of merchantability and fitness,  /*         
  24520. /* are expressly denied.                                             /*         
  24521. /*                                                                   /*         
  24522. /* Provided this copyright notice is included, this software may     /*         
  24523. /* be freely distributed and not offered for sale.                   /*         
  24524. /*                                                                   /*         
  24525. /* Changes or modifications may be made and used only by the maker   /*         
  24526. /* of same, and not further distributed.  Such modifications should  /*         
  24527. /* be mailed to the author for consideration for addition to the     /*         
  24528. /* software and incorporation in subsequent releases.                /*         
  24529. /*                                                                   /*         
  24530.  ^ TYPE(DATAOUT) INTENS(HIGH) COLOR(TURQ) HILITE(REVERSE)                       
  24531.  / TYPE(DATAOUT) INTENS(HIGH) COLOR(TURQ)                                       
  24532.  * AREA(DYNAMIC)                                                                
  24533.  $ TYPE(TEXT) INTENS(LOW)                                                       
  24534.  # TYPE(OUTPUT) INTENS(HIGH)                                                    
  24535. )BODY EXPAND(``)                                                                
  24536. |-`-`-  MVS Network News Connection -`-`-                                       
  24537. +                                                                               
  24538.                                                                                 
  24539.          Now retrieving the titles of the articles in newsgroup:                
  24540.         |&NNGROUP                                                               
  24541. +                                                                               
  24542.          &MSG                                                                   
  24543. +        ------------------------------------------------------------           
  24544.         *NNMBAR                                                     *|&TODO     
  24545. +        ------------------------------------------------------------           
  24546.         0%                          50%                              100%       
  24547.                                                                                 
  24548.         $Estimated time to completion:#NNMESTM +                                
  24549.                                                                                 
  24550.      This may take a long time, depending on the number of articles.            
  24551.                                                                                 
  24552.                                                                                 
  24553. |                                  Please wait.                                 
  24554.                                                                                 
  24555. )INIT                                                                           
  24556.  IF (&NNMESTM = &Z)                                                             
  24557.    .ATTRCHAR($) = 'INTENS(NON)'                                                 
  24558.    .ATTRCHAR(#) = 'INTENS(NON)'                                                 
  24559.  IF (&NNMCOUNT = -1)                                                            
  24560.   &TODO = &Z                                                                    
  24561.   &MSG = 'Articles processed so far while searching:'                           
  24562.  ELSE                                                                           
  24563.   &TODO = &NNMCOUNT                                                             
  24564.   &MSG = 'Percentage of articles processed so far:'                             
  24565. )PROC                                                                           
  24566. )END                                                                            
  24567. ./   ADD NAME=NNMLCONN,SSI=01030000                                             
  24568. )ATTR                                                                           
  24569. /*                                                                   /*         
  24570. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24571. /*                                                                   /*         
  24572. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24573. /* including the implied warranties of merchantability and fitness,  /*         
  24574. /* are expressly denied.                                             /*         
  24575. /*                                                                   /*         
  24576. /* Provided this copyright notice is included, this software may     /*         
  24577. /* be freely distributed and not offered for sale.                   /*         
  24578. /*                                                                   /*         
  24579. /* Changes or modifications may be made and used only by the maker   /*         
  24580. /* of same, and not further distributed.  Such modifications should  /*         
  24581. /* be mailed to the author for consideration for addition to the     /*         
  24582. /* software and incorporation in subsequent releases.                /*         
  24583. /*                                                                   /*         
  24584.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  24585.  @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)                                          
  24586.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  24587.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  24588.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  24589.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  24590.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  24591. )BODY EXPAND(``)                                                                
  24592. %-`-`-  MVS Network News Connection -`-`-                                       
  24593. +                                                                               
  24594. +             Client name: &NNCLIENT    Client IP address:  &NNCLIEIP           
  24595. +                                                                               
  24596. +                                                                               
  24597. +             Connection is in progress for news server at:                     
  24598.               &NNSERVER (&NNSERVIP)                                             
  24599. +                                                                               
  24600. +                                                                               
  24601.                                  % Please wait.                                 
  24602. +                                                                               
  24603. +                                                                               
  24604. )INIT                                                                           
  24605. )PROC                                                                           
  24606. )END                                                                            
  24607. ./   ADD NAME=NNMLDISC,SSI=01050000                                             
  24608. )ATTR                                                                           
  24609. /*                                                                   /*         
  24610. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24611. /*                                                                   /*         
  24612. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24613. /* including the implied warranties of merchantability and fitness,  /*         
  24614. /* are expressly denied.                                             /*         
  24615. /*                                                                   /*         
  24616. /* Provided this copyright notice is included, this software may     /*         
  24617. /* be freely distributed and not offered for sale.                   /*         
  24618. /*                                                                   /*         
  24619. /* Changes or modifications may be made and used only by the maker   /*         
  24620. /* of same, and not further distributed.  Such modifications should  /*         
  24621. /* be mailed to the author for consideration for addition to the     /*         
  24622. /* software and incorporation in subsequent releases.                /*         
  24623. /*                                                                   /*         
  24624.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  24625.  @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)                                          
  24626.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  24627.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  24628.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  24629.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  24630.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  24631. )BODY EXPAND(``)                                                                
  24632. %-`-`-  MVS Network News Connection -`-`-                                       
  24633. +                                                                               
  24634. +                                                                               
  24635. +         Disconnection is in progress from the news server at:                 
  24636.           &NNSOLDER (&NNSOLDIP)                                                 
  24637. +                                                                               
  24638. +                                                                               
  24639.                                  % Please wait.                                 
  24640. +                                                                               
  24641. +                                                                               
  24642. )INIT                                                                           
  24643. )PROC                                                                           
  24644. )END                                                                            
  24645. ./   ADD NAME=NNMLEXN2,SSI=01010000                                             
  24646. )ATTR                                                                           
  24647. /*                                                                   /*         
  24648. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24649. /*                                                                   /*         
  24650. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24651. /* including the implied warranties of merchantability and fitness,  /*         
  24652. /* are expressly denied.                                             /*         
  24653. /*                                                                   /*         
  24654. /* Provided this copyright notice is included, this software may     /*         
  24655. /* be freely distributed and not offered for sale.                   /*         
  24656. /*                                                                   /*         
  24657. /* Changes or modifications may be made and used only by the maker   /*         
  24658. /* of same, and not further distributed.  Such modifications should  /*         
  24659. /* be mailed to the author for consideration for addition to the     /*         
  24660. /* software and incorporation in subsequent releases.                /*         
  24661. /*                                                                   /*         
  24662.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  24663.  @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)                                          
  24664.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  24665.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  24666.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  24667.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  24668. )BODY EXPAND(``)                                                                
  24669. %-`-`-  MVS Network News Connection -`-`-                                       
  24670. +                                                                               
  24671. +Newsgroup: &NNLGROUP                                                           
  24672. +                                                                               
  24673. +Article #:%&NNTNUM                                                             
  24674. +Subject:   &NNTSUBJ                                                            
  24675. +                                                                               
  24676. +Extracting to: &NNEXDSN                                                        
  24677. +&MEMSTUFF                                                                      
  24678. +                                                                               
  24679.                                  % Please wait.                                 
  24680. +                                                                               
  24681. )INIT                                                                           
  24682.  IF (&NNEXMEM = &Z) &MEMSTUFF = &Z                                              
  24683.  ELSE               &MEMSTUFF = 'Member: &NNEXMEM'                              
  24684. )PROC                                                                           
  24685. )END                                                                            
  24686. ./   ADD NAME=NNMLLIST,SSI=01030000                                             
  24687. )ATTR                                                                           
  24688. /*                                                                   /*         
  24689. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24690. /*                                                                   /*         
  24691. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24692. /* including the implied warranties of merchantability and fitness,  /*         
  24693. /* are expressly denied.                                             /*         
  24694. /*                                                                   /*         
  24695. /* Provided this copyright notice is included, this software may     /*         
  24696. /* be freely distributed and not offered for sale.                   /*         
  24697. /*                                                                   /*         
  24698. /* Changes or modifications may be made and used only by the maker   /*         
  24699. /* of same, and not further distributed.  Such modifications should  /*         
  24700. /* be mailed to the author for consideration for addition to the     /*         
  24701. /* software and incorporation in subsequent releases.                /*         
  24702. /*                                                                   /*         
  24703.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  24704.  @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)                                          
  24705.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  24706.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  24707.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  24708.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  24709.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  24710. )BODY EXPAND(``)                                                                
  24711. %-`-`-  MVS Network News Connection -`-`-                                       
  24712. +                                                                               
  24713. +                                                                               
  24714.        A list of all newsgroups is being retrieved from the news server at:     
  24715.        &NNSERVER (&NNSERVIP)                                                    
  24716. +                                                                               
  24717.      This may take a long time, depending on the number of newsgroups known.    
  24718. +                                                                               
  24719. +                                                                               
  24720.                                  % Please wait.                                 
  24721. +                                                                               
  24722. +                                                                               
  24723. )INIT                                                                           
  24724. )PROC                                                                           
  24725. )END                                                                            
  24726. ./   ADD NAME=NNMLNEWG,SSI=01000032                                             
  24727. )ATTR                                                                           
  24728. /*                                                                   /*         
  24729. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24730. /*                                                                   /*         
  24731. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  24732. /*                                                                   /*         
  24733. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24734. /* including the implied warranties of merchantability and fitness,  /*         
  24735. /* are expressly denied.                                             /*         
  24736. /*                                                                   /*         
  24737. /* Provided this copyright notice is included, this software may     /*         
  24738. /* be freely distributed and not offered for sale.                   /*         
  24739. /*                                                                   /*         
  24740. /* Changes or modifications may be made and used only by the maker   /*         
  24741. /* of same, and not further distributed.  Such modifications should  /*         
  24742. /* be mailed to the author for consideration for addition to the     /*         
  24743. /* software and incorporation in subsequent releases.                /*         
  24744. /*                                                                   /*         
  24745.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  24746.  @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)                                          
  24747.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  24748.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  24749.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  24750.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  24751.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  24752. )BODY EXPAND(``)                                                                
  24753. %-`-`-  MVS Network News Connection -`-`-                                       
  24754. +                                                                               
  24755. +                                                                               
  24756.        A list of new newsgroups since &NNNGDT &NNNGTM is being retrieved        
  24757. +      from the news server at:  &NNSERVER (&NNSERVIP)                          
  24758. +                                                                               
  24759.      This may take a long time, depending on the number of newsgroups known.    
  24760. +                                                                               
  24761. +                                                                               
  24762.                                  % Please wait.                                 
  24763. +                                                                               
  24764. +                                                                               
  24765. )INIT                                                                           
  24766. )PROC                                                                           
  24767. )END                                                                            
  24768. ./   ADD NAME=NNMLRCON,SSI=01020000                                             
  24769. )ATTR                                                                           
  24770. /*                                                                   /*         
  24771. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24772. /*                                                                   /*         
  24773. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24774. /* including the implied warranties of merchantability and fitness,  /*         
  24775. /* are expressly denied.                                             /*         
  24776. /*                                                                   /*         
  24777. /* Provided this copyright notice is included, this software may     /*         
  24778. /* be freely distributed and not offered for sale.                   /*         
  24779. /*                                                                   /*         
  24780. /* Changes or modifications may be made and used only by the maker   /*         
  24781. /* of same, and not further distributed.  Such modifications should  /*         
  24782. /* be mailed to the author for consideration for addition to the     /*         
  24783. /* software and incorporation in subsequent releases.                /*         
  24784. /*                                                                   /*         
  24785.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  24786.  @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)                                          
  24787.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  24788.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  24789.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  24790.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  24791.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  24792. )BODY EXPAND(``)                                                                
  24793. %-`-`-  MVS Network News Connection -`-`-                                       
  24794. +                                                                               
  24795.         +Connection has apparently been lost to the news server at:             
  24796.         &NNSERVER (&NNSERVIP)                                                   
  24797. +                                                                               
  24798.                 +Reconnection to the server is in progress.                     
  24799. +                                                                               
  24800.                                  % Please wait.                                 
  24801. +                                                                               
  24802. +                                                                               
  24803. )INIT                                                                           
  24804. )PROC                                                                           
  24805. )END                                                                            
  24806. ./   ADD NAME=NNMLRETG,SSI=01010000                                             
  24807. )ATTR                                                                           
  24808. /*                                                                   /*         
  24809. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24810. /*                                                                   /*         
  24811. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24812. /* including the implied warranties of merchantability and fitness,  /*         
  24813. /* are expressly denied.                                             /*         
  24814. /*                                                                   /*         
  24815. /* Provided this copyright notice is included, this software may     /*         
  24816. /* be freely distributed and not offered for sale.                   /*         
  24817. /*                                                                   /*         
  24818. /* Changes or modifications may be made and used only by the maker   /*         
  24819. /* of same, and not further distributed.  Such modifications should  /*         
  24820. /* be mailed to the author for consideration for addition to the     /*         
  24821. /* software and incorporation in subsequent releases.                /*         
  24822. /*                                                                   /*         
  24823.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  24824.  @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)                                          
  24825.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  24826.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  24827.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  24828.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  24829.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  24830. )BODY EXPAND(``)                                                                
  24831. %-`-`-  MVS Network News Connection -`-`-                                       
  24832. +                                                                               
  24833. +                                                                               
  24834.          Retrieving current status of newsgroup:                                
  24835. %        &NNLGROUP                                                              
  24836. +                                                                               
  24837. +                                                                               
  24838.                                  % Please wait.                                 
  24839. +                                                                               
  24840. +                                                                               
  24841. )INIT                                                                           
  24842. )PROC                                                                           
  24843. )END                                                                            
  24844. ./   ADD NAME=NNMLRET2,SSI=01000019                                             
  24845. )ATTR DEFAULT(|+_)                                                              
  24846. /*                                                                   /*         
  24847. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24848. /*                                                                   /*         
  24849. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  24850. /*                                                                   /*         
  24851. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24852. /* including the implied warranties of merchantability and fitness,  /*         
  24853. /* are expressly denied.                                             /*         
  24854. /*                                                                   /*         
  24855. /* Provided this copyright notice is included, this software may     /*         
  24856. /* be freely distributed and not offered for sale.                   /*         
  24857. /*                                                                   /*         
  24858. /* Changes or modifications may be made and used only by the maker   /*         
  24859. /* of same, and not further distributed.  Such modifications should  /*         
  24860. /* be mailed to the author for consideration for addition to the     /*         
  24861. /* software and incorporation in subsequent releases.                /*         
  24862. /*                                                                   /*         
  24863.  ^ TYPE(DATAOUT) INTENS(HIGH) COLOR(TURQ) HILITE(REVERSE)                       
  24864.  / TYPE(DATAOUT) INTENS(HIGH) COLOR(TURQ)                                       
  24865.  * AREA(DYNAMIC)                                                                
  24866.  $ TYPE(TEXT) INTENS(LOW)                                                       
  24867.  # TYPE(OUTPUT) INTENS(HIGH)                                                    
  24868. )BODY EXPAND(``)                                                                
  24869. |-`-`-  MVS Network News Connection -`-`-                                       
  24870. +                                                                               
  24871. +                                                                               
  24872. +        Retrieving current status of registered newsgroups                     
  24873. +                                                                               
  24874. +                                                                               
  24875. +        Percentage of registered newsgroups processed:                         
  24876. +        ------------------------------------------------------------           
  24877. +       *NNMBAR                                                     *|&NNMCOUNT 
  24878. +        ------------------------------------------------------------           
  24879. +       0%                          50%                              100%       
  24880. +                                                                               
  24881. +       $Estimated time to completion:#NNMESTM +                                
  24882. +                                                                               
  24883. )INIT                                                                           
  24884.  IF (&NNMESTM = &Z)                                                             
  24885.    .ATTRCHAR($) = 'INTENS(NON)'                                                 
  24886.    .ATTRCHAR(#) = 'INTENS(NON)'                                                 
  24887. )PROC                                                                           
  24888. )END                                                                            
  24889. ./   ADD NAME=NNMLRET3,SSI=01000044                                             
  24890. )ATTR DEFAULT(|+_)                                                              
  24891. /*                                                                   /*         
  24892. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24893. /*                                                                   /*         
  24894. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  24895. /*                                                                   /*         
  24896. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24897. /* including the implied warranties of merchantability and fitness,  /*         
  24898. /* are expressly denied.                                             /*         
  24899. /*                                                                   /*         
  24900. /* Provided this copyright notice is included, this software may     /*         
  24901. /* be freely distributed and not offered for sale.                   /*         
  24902. /*                                                                   /*         
  24903. /* Changes or modifications may be made and used only by the maker   /*         
  24904. /* of same, and not further distributed.  Such modifications should  /*         
  24905. /* be mailed to the author for consideration for addition to the     /*         
  24906. /* software and incorporation in subsequent releases.                /*         
  24907. /*                                                                   /*         
  24908.  ^ TYPE(DATAOUT) INTENS(HIGH) COLOR(TURQ) HILITE(REVERSE)                       
  24909.  / TYPE(DATAOUT) INTENS(HIGH) COLOR(TURQ)                                       
  24910.  * AREA(DYNAMIC)                                                                
  24911.  $ TYPE(TEXT) INTENS(LOW)                                                       
  24912.  # TYPE(OUTPUT) INTENS(HIGH)                                                    
  24913. )BODY EXPAND(``)                                                                
  24914. |-`-`-  MVS Network News Connection -`-`-                                       
  24915. +                                                                               
  24916. +                                                                               
  24917. +        Retrieving current status of newsgroup:                                
  24918. |        &NNLGROUP                                                              
  24919. +                                                                               
  24920. +        Percentage of registered newsgroups processed:                         
  24921. +        ------------------------------------------------------------           
  24922. +       *NNMBAR                                                     *|&NNMCOUNT 
  24923. +        ------------------------------------------------------------           
  24924. +       0%                          50%                              100%       
  24925. +                                                                               
  24926. +       $Estimated time to completion:#NNMESTM +                                
  24927. +                                                                               
  24928. )INIT                                                                           
  24929.  IF (&NNMESTM = &Z)                                                             
  24930.    .ATTRCHAR($) = 'INTENS(NON)'                                                 
  24931.    .ATTRCHAR(#) = 'INTENS(NON)'                                                 
  24932. )PROC                                                                           
  24933. )END                                                                            
  24934. ./   ADD NAME=NNMLRSNG,SSI=01020000                                             
  24935. )ATTR                                                                           
  24936. /*                                                                   /*         
  24937. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24938. /*                                                                   /*         
  24939. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24940. /* including the implied warranties of merchantability and fitness,  /*         
  24941. /* are expressly denied.                                             /*         
  24942. /*                                                                   /*         
  24943. /* Provided this copyright notice is included, this software may     /*         
  24944. /* be freely distributed and not offered for sale.                   /*         
  24945. /*                                                                   /*         
  24946. /* Changes or modifications may be made and used only by the maker   /*         
  24947. /* of same, and not further distributed.  Such modifications should  /*         
  24948. /* be mailed to the author for consideration for addition to the     /*         
  24949. /* software and incorporation in subsequent releases.                /*         
  24950. /*                                                                   /*         
  24951.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  24952.  @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)                                          
  24953.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  24954.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  24955.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  24956.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  24957.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  24958. )BODY EXPAND(``)                                                                
  24959. %-`-`-  MVS Network News Connection -`-`-                                       
  24960. +                                                                               
  24961. +         Reconnection has been established to the news server at:              
  24962.           &NNSERVER (&NNSERVIP)                                                 
  24963. +                                                                               
  24964.           Now reestablishing current newsgroup:                                 
  24965. %         &NNGROUP                                                              
  24966. +                                                                               
  24967.                                  % Please wait.                                 
  24968. +                                                                               
  24969. +                                                                               
  24970. )INIT                                                                           
  24971. )PROC                                                                           
  24972. )END                                                                            
  24973. ./   ADD NAME=NNMLUNRC,SSI=01000004                                             
  24974. )ATTR                                                                           
  24975. /*                                                                   /*         
  24976. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  24977. /*                                                                   /*         
  24978. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  24979. /*                                                                   /*         
  24980. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  24981. /* including the implied warranties of merchantability and fitness,  /*         
  24982. /* are expressly denied.                                             /*         
  24983. /*                                                                   /*         
  24984. /* Provided this copyright notice is included, this software may     /*         
  24985. /* be freely distributed and not offered for sale.                   /*         
  24986. /*                                                                   /*         
  24987. /* Changes or modifications may be made and used only by the maker   /*         
  24988. /* of same, and not further distributed.  Such modifications should  /*         
  24989. /* be mailed to the author for consideration for addition to the     /*         
  24990. /* software and incorporation in subsequent releases.                /*         
  24991. /*                                                                   /*         
  24992.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  24993.  @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)                                          
  24994.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  24995.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  24996.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  24997.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  24998.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  24999. )BODY EXPAND(``)                                                                
  25000. %-`-`-  MVS Network News Connection -`-`-                                       
  25001. +                                                                               
  25002. +                                                                               
  25003. +                       Updating NEWSRC file &NNNEWSRF ...                      
  25004. +                                                                               
  25005. +                                                                               
  25006. +                                                                               
  25007. %                                  Please wait.                                 
  25008. +                                                                               
  25009. +                                                                               
  25010. )INIT                                                                           
  25011. )PROC                                                                           
  25012. )END                                                                            
  25013. ./   ADD NAME=NNMOPTS,SSI=010A0016                                              
  25014. )ATTR                                                                           
  25015. /*                                                                   /*         
  25016. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25017. /*                                                                   /*         
  25018. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  25019. /*                                                                   /*         
  25020. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25021. /* including the implied warranties of merchantability and fitness,  /*         
  25022. /* are expressly denied.                                             /*         
  25023. /*                                                                   /*         
  25024. /* Provided this copyright notice is included, this software may     /*         
  25025. /* be freely distributed and not offered for sale.                   /*         
  25026. /*                                                                   /*         
  25027. /* Changes or modifications may be made and used only by the maker   /*         
  25028. /* of same, and not further distributed.  Such modifications should  /*         
  25029. /* be mailed to the author for consideration for addition to the     /*         
  25030. /* software and incorporation in subsequent releases.                /*         
  25031. /*                                                                   /*         
  25032. )BODY EXPAND(``)                                                                
  25033. %-`-`- NNMVS - Article Retrieval Options -`-`-                                  
  25034. %Command ===>_ZCMD                                                              
  25035. +                                                                               
  25036. %General options:                                                               
  25037.                                                                                 
  25038. +In-progress screen for adding newsgroups?  (YES/NO)%==>_Z  +                   
  25039. +In-progress screen for rewriting NEWSRC?   (YES/NO)%==>_Z  +                   
  25040. +In-progress screen for retrieving articles?(YES/NO)%==>_Z  +                   
  25041.                                                                                 
  25042. +Screen update frequency   %==>_Z       + (Enter%ON, OFF,+or%number+of seconds) 
  25043.                                                                                 
  25044. %EXTRACT prompting options:                                                     
  25045.                                                                                 
  25046. +Warning panel before writing over an existing dataset?%==>_Z  +                
  25047. +Warning panel before appending to an existing dataset?%==>_Z  +                
  25048.                                                                                 
  25049. +Press%ENTER+to change options.  Press%&END+(or type%END+command) when done.    
  25050. )INIT                                                                           
  25051.  .ZVARS  = '(NNUPAN NNUPRN NNUPRA NNMUPDTF NNEXTPOW NNEXTPAP)'                  
  25052.  .HELP   = TNNMOPT                                                              
  25053.  .CURSOR = ZCMD                                                                 
  25054.  &END = PFK(END)                                                                
  25055.  &ZCMD = &Z                                                                     
  25056.  VGET (NNUPAN NNUPRN NNUPRA NNMUPDTF NNEXTPOW NNEXTPAP) PROFILE                 
  25057.  IF (&NNMUPDTF = &Z) &NNMUPDTF = '5'                                            
  25058.  &NNUPAN   = TRANS(TRUNC(&NNUPAN,1)   Y,YES N,NO *,NO )                         
  25059.  &NNUPRN   = TRANS(TRUNC(&NNUPRN,1)   Y,YES N,NO *,YES)                         
  25060.  &NNUPRA   = TRANS(TRUNC(&NNUPRA,1)   Y,YES N,NO *,YES)                         
  25061.  &NNEXTPOW = TRANS(TRUNC(&NNEXTPOW,1) Y,YES N,NO *,YES)                         
  25062.  &NNEXTPAP = TRANS(TRUNC(&NNEXTPAP,1) Y,YES N,NO *,YES)                         
  25063. )PROC                                                                           
  25064.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25065.  IF (.RESP = ENTER)                                                             
  25066.   VER(&NNMUPDTF,NB)                                                             
  25067.   IF (&NNMUPDTF = '0')  &NNMUPDTF = 'ON'                                        
  25068.   IF (&NNMUPDTF = 'ON','OFF')                                                   
  25069.   ELSE                                                                          
  25070.     VER(&NNMUPDTF,NUM)                                                          
  25071.   &NNUPAN   = TRANS(&NNUPAN   YES,Y NO,N)                                       
  25072.   &NNUPRN   = TRANS(&NNUPRN   YES,Y NO,N)                                       
  25073.   &NNUPRA   = TRANS(&NNUPRA   YES,Y NO,N)                                       
  25074.   &NNEXTPOW = TRANS(&NNEXTPOW YES,Y NO,N)                                       
  25075.   &NNEXTPAP = TRANS(&NNEXTPAP YES,Y NO,N)                                       
  25076.   VER(&NNUPAN  ,NB,LIST,Y,N)                                                    
  25077.   VER(&NNUPRN  ,NB,LIST,Y,N)                                                    
  25078.   VER(&NNUPRA  ,NB,LIST,Y,N)                                                    
  25079.   VER(&NNEXTPOW,NB,LIST,Y,N)                                                    
  25080.  VPUT (NNUPAN NNUPRN NNUPRA NNMUPDTF NNEXTPOW NNEXTPAP) PROFILE                 
  25081. )END                                                                            
  25082. ./   ADD NAME=NNMOPTT,SSI=01010039                                              
  25083. )ATTR                                                                           
  25084. /*                                                                   /*         
  25085. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25086. /*                                                                   /*         
  25087. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  25088. /*                                                                   /*         
  25089. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25090. /* including the implied warranties of merchantability and fitness,  /*         
  25091. /* are expressly denied.                                             /*         
  25092. /*                                                                   /*         
  25093. /* Provided this copyright notice is included, this software may     /*         
  25094. /* be freely distributed and not offered for sale.                   /*         
  25095. /*                                                                   /*         
  25096. /* Changes or modifications may be made and used only by the maker   /*         
  25097. /* of same, and not further distributed.  Such modifications should  /*         
  25098. /* be mailed to the author for consideration for addition to the     /*         
  25099. /* software and incorporation in subsequent releases.                /*         
  25100. /*                                                                   /*         
  25101. )BODY EXPAND(``)                                                                
  25102. %-`-`- NNMVS - Table Viewing Options -`-`-                                      
  25103. %Command ===>_ZCMD                                                              
  25104. +                                                                               
  25105. %Newsgroup table options:                                                       
  25106.                                                                                 
  25107. +Scroll last selected newsgroup to top? (YES/NO)%==>_Z  +                       
  25108.                                                                                 
  25109.                                                                                 
  25110. %Article table options:                                                         
  25111.                                                                                 
  25112. +Scroll last selected article to top?   (YES/NO)%==>_Z  +                       
  25113.                                                                                 
  25114. +Number of heading rows to display per article  %==>_Z+  (Enter%1, 2+or%3+only) 
  25115.                                                                                 
  25116.                                                                                 
  25117. +Press%ENTER+to change options.  Press%&END+(or type%END+command) when done.    
  25118. )INIT                                                                           
  25119.  .ZVARS  = '(NNNGSCR NNARSCR NNARROWS)'                                         
  25120.  .HELP   = TNNMOPT                                                              
  25121.  .CURSOR = ZCMD                                                                 
  25122.  &END = PFK(END)                                                                
  25123.  &ZCMD = &Z                                                                     
  25124.  VGET (NNNGSCR NNARSCR NNARROWS) PROFILE                                        
  25125.  &NNNGSCR  = TRANS(TRUNC(&NNNGSCR,1)  Y,YES N,NO *,YES)                         
  25126.  &NNARSCR  = TRANS(TRUNC(&NNARSCR,1)  Y,YES N,NO *,YES)                         
  25127.  &NNARROWS = TRANS(&NNARROWS 1,1 2,2 3,3 *,1)                                   
  25128. )PROC                                                                           
  25129.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25130.  IF (.RESP = ENTER)                                                             
  25131.   &NNNGSCR  = TRANS(&NNNGSCR  YES,Y NO,N)                                       
  25132.   &NNARSCR  = TRANS(&NNARSCR  YES,Y NO,N)                                       
  25133.   VER(&NNNGSCR,NB,LIST,Y,N)                                                     
  25134.   VER(&NNARSCR,NB,LIST,Y,N)                                                     
  25135.   VER(&NNARROWS,NB,LIST,1,2,3)                                                  
  25136.  VPUT (NNNGSCR NNARSCR NNARROWS) PROFILE                                        
  25137. )END                                                                            
  25138. ./   ADD NAME=NNMPAUTH,SSI=01050017                                             
  25139. )ATTR                                                                           
  25140. /*                                                                   /*         
  25141. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25142. /*                                                                   /*         
  25143. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25144. /* including the implied warranties of merchantability and fitness,  /*         
  25145. /* are expressly denied.                                             /*         
  25146. /*                                                                   /*         
  25147. /* Provided this copyright notice is included, this software may     /*         
  25148. /* be freely distributed and not offered for sale.                   /*         
  25149. /*                                                                   /*         
  25150. /* Changes or modifications may be made and used only by the maker   /*         
  25151. /* of same, and not further distributed.  Such modifications should  /*         
  25152. /* be mailed to the author for consideration for addition to the     /*         
  25153. /* software and incorporation in subsequent releases.                /*         
  25154. /*                                                                   /*         
  25155. )BODY WINDOW(62,14)                                                             
  25156. +                                                                               
  25157. %Command ===>_ZCMD                                                              
  25158. +                                                                               
  25159.  NNMVS could not obtain authorization from the NNTP server.                     
  25160.  You may proceed, but you should be aware that some news                        
  25161.  reading or posting operations may fail.                                        
  25162.                                                                                 
  25163.  The response from server &NNSERVER was:                                        
  25164.                                                                                 
  25165. %&NNSRVRSP                                                                      
  25166. +                                                                               
  25167.  Press%ENTER+to proceed.                                                        
  25168.  Press%END  +to return to the NNMVS primary menu.                               
  25169. )INIT                                                                           
  25170.  .HELP = TNNM                                                                   
  25171.  &ZWINTTL = 'Server authorization failed'                                       
  25172.  &END = PFK(END)                                                                
  25173.  &ZCMD = &Z                                                                     
  25174. )PROC                                                                           
  25175.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25176. )END                                                                            
  25177. ./   ADD NAME=NNMPCAN,SSI=01000015                                              
  25178. )ATTR                                                                           
  25179. /*                                                                   /*         
  25180. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25181. /*                                                                   /*         
  25182. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25183. /* including the implied warranties of merchantability and fitness,  /*         
  25184. /* are expressly denied.                                             /*         
  25185. /*                                                                   /*         
  25186. /* Provided this copyright notice is included, this software may     /*         
  25187. /* be freely distributed and not offered for sale.                   /*         
  25188. /*                                                                   /*         
  25189. /* Changes or modifications may be made and used only by the maker   /*         
  25190. /* of same, and not further distributed.  Such modifications should  /*         
  25191. /* be mailed to the author for consideration for addition to the     /*         
  25192. /* software and incorporation in subsequent releases.                /*         
  25193. /*                                                                   /*         
  25194.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25195. )BODY WINDOW(64,14)                                                             
  25196. +                                                                               
  25197. %Command ===>^ZCMD                                                              
  25198. +                                                                               
  25199. +Newsgroup :%&NNCGROUP                                                          
  25200. +Article:   %&NNCNUM                                                            
  25201. +Message-ID:%&NNCMSGID                                                          
  25202. +Subject:   %&NNCSUBJ                                                           
  25203.                                                                                 
  25204.                                                                                 
  25205. +This action will forward a CANCEL request to the news server.                  
  25206. +                                                                               
  25207. +Press%ENTER+to proceed to cancel this article.                                 
  25208. +                                                                               
  25209. +Press%&END (END)+to abandon the request and leave the article.                 
  25210. )INIT                                                                           
  25211.  .HELP = TNNM                                                                   
  25212.  &ZWINTTL = 'Confirm Article Cancellation'                                      
  25213.  &END = PFK(END)                                                                
  25214. )PROC                                                                           
  25215.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25216. )END                                                                            
  25217. ./   ADD NAME=NNMPCONM,SSI=01040055                                             
  25218. )ATTR                                                                           
  25219. /*                                                                   /*         
  25220. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25221. /*                                                                   /*         
  25222. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25223. /* including the implied warranties of merchantability and fitness,  /*         
  25224. /* are expressly denied.                                             /*         
  25225. /*                                                                   /*         
  25226. /* Provided this copyright notice is included, this software may     /*         
  25227. /* be freely distributed and not offered for sale.                   /*         
  25228. /*                                                                   /*         
  25229. /* Changes or modifications may be made and used only by the maker   /*         
  25230. /* of same, and not further distributed.  Such modifications should  /*         
  25231. /* be mailed to the author for consideration for addition to the     /*         
  25232. /* software and incorporation in subsequent releases.                /*         
  25233. /*                                                                   /*         
  25234. )BODY WINDOW(49,10)                                                             
  25235. +                                                                               
  25236. %Command ===>_ZCMD                                                              
  25237.                                                                                 
  25238. +To:     %&NNMAILTO                                                             
  25239. +Subject:%&NNMAILSJ                                                             
  25240.                                                                                 
  25241. +Press%ENTER     +to mail this message.                                         
  25242. +Press%&END (END)+to return to the mail menu.                                   
  25243. +Enter%CANCEL    +to cancel the message.                                        
  25244. )INIT                                                                           
  25245.  .HELP = TNNM                                                                   
  25246.  &ZWINTTL = 'Confirm mailing'                                                   
  25247.  &END = PFK(END)                                                                
  25248.  &ZCMD = &Z                                                                     
  25249. )PROC                                                                           
  25250.  VER(&ZCMD,LIST,CAN,CANCEL)                                                     
  25251. )END                                                                            
  25252. ./   ADD NAME=NNMPCONP,SSI=01040000                                             
  25253. )ATTR                                                                           
  25254. /*                                                                   /*         
  25255. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25256. /*                                                                   /*         
  25257. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25258. /* including the implied warranties of merchantability and fitness,  /*         
  25259. /* are expressly denied.                                             /*         
  25260. /*                                                                   /*         
  25261. /* Provided this copyright notice is included, this software may     /*         
  25262. /* be freely distributed and not offered for sale.                   /*         
  25263. /*                                                                   /*         
  25264. /* Changes or modifications may be made and used only by the maker   /*         
  25265. /* of same, and not further distributed.  Such modifications should  /*         
  25266. /* be mailed to the author for consideration for addition to the     /*         
  25267. /* software and incorporation in subsequent releases.                /*         
  25268. /*                                                                   /*         
  25269. )BODY WINDOW(49,10)                                                             
  25270. +                                                                               
  25271. %Command ===>_ZCMD                                                              
  25272.                                                                                 
  25273. +Newsgroups:%&NNPOSTNG                                                          
  25274. +Subject:   %&NNPOSTSJ                                                          
  25275.                                                                                 
  25276. +Press%ENTER     +to post this article.                                         
  25277. +Press%&END (END)+to return to the posting menu.                                
  25278. +Enter%CANCEL    +to cancel the post.                                           
  25279. )INIT                                                                           
  25280.  .HELP = TNNM                                                                   
  25281.  &ZWINTTL = 'Confirm posting'                                                   
  25282.  &END = PFK(END)                                                                
  25283.  &ZCMD = &Z                                                                     
  25284. )PROC                                                                           
  25285.  VER(&ZCMD,LIST,CAN,CANCEL)                                                     
  25286. )END                                                                            
  25287. ./   ADD NAME=NNMPEXDS,SSI=01150041                                             
  25288. )ATTR                                                                           
  25289. /*                                                                   /*         
  25290. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25291. /*                                                                   /*         
  25292. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25293. /* including the implied warranties of merchantability and fitness,  /*         
  25294. /* are expressly denied.                                             /*         
  25295. /*                                                                   /*         
  25296. /* Provided this copyright notice is included, this software may     /*         
  25297. /* be freely distributed and not offered for sale.                   /*         
  25298. /*                                                                   /*         
  25299. /* Changes or modifications may be made and used only by the maker   /*         
  25300. /* of same, and not further distributed.  Such modifications should  /*         
  25301. /* be mailed to the author for consideration for addition to the     /*         
  25302. /* software and incorporation in subsequent releases.                /*         
  25303. /*                                                                   /*         
  25304.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25305. )BODY WINDOW(77,16)                                                             
  25306. +                                                                               
  25307. %Command ===>^ZCMD                                                              
  25308. +                                                                               
  25309. +&NUMBER       %&SUBJECT                                                        
  25310. +                                                                               
  25311. +Save to data set ===>_NNEXDSN                                                  
  25312. +Expand tab characters?       ===>_Z  +                                         
  25313.                                                                                 
  25314. +(Note: Data set will be RECFM=VB, LRECL=259, BLKSIZE=6233.)                    
  25315.                                                                                 
  25316. +Append to end of data set?   ===>_Z  +                                         
  25317. +Blank line after separator?  ===>_Z  +                                         
  25318. +Separator line between articles (append mode only...blank for none):           
  25319. +>^Z                                                                       +<   
  25320.                                                                                 
  25321. +Press%&END (END)+to cancel the extract request.                                
  25322. )INIT                                                                           
  25323.  .HELP = TNNM                                                                   
  25324.  .ZVARS = '(NNEXTAB NNEXAPP NNEXBLK NNEXSEP)'                                   
  25325.  .CURSOR = NNEXDSN                                                              
  25326.  IF (&NNTNUM ^= &Z)                                                             
  25327.   &ZWINTTL = 'Extract from &NNGROUP'                                            
  25328.   &NUMBER  = 'Article &NNTNUM: '                                                
  25329.   &SUBJECT = '&NNTSUBJ'                                                         
  25330.  ELSE                                                                           
  25331.   &ZWINTTL = 'Extract text'                                                     
  25332.   &NUMBER  = ' '                                                                
  25333.   &SUBJECT = ' '                                                                
  25334.  &END = PFK(END)                                                                
  25335.  &ZCMD = &Z                                                                     
  25336.  VGET (NNEXDSN NNEXTAB NNEXAPP NNEXBLK NNEXSEP) PROFILE                         
  25337.  &NNEXTAB = TRANS(&NNEXTAB Y,YES N,NO ' ',NO)                                   
  25338.  &NNEXAPP = TRANS(&NNEXAPP Y,YES N,NO ' ',NO)                                   
  25339.  &NNEXBLK = TRANS(&NNEXBLK Y,YES N,NO ' ',NO)                                   
  25340. )PROC                                                                           
  25341.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25342.  VER(&NNEXDSN,NB,DSNAME)                                                        
  25343.  &NNEXTAB = TRUNC(&NNEXTAB,1)                                                   
  25344.  VER(&NNEXTAB,NB,LIST,Y,N)                                                      
  25345.  &NNEXAPP = TRUNC(&NNEXAPP,1)                                                   
  25346.  VER(&NNEXAPP,NB,LIST,Y,N)                                                      
  25347.  &NNEXBLK = TRUNC(&NNEXBLK,1)                                                   
  25348.  VER(&NNEXBLK,NB,LIST,Y,N)                                                      
  25349.  VPUT (NNEXDSN NNEXTAB NNEXAPP NNEXBLK NNEXSEP) PROFILE                         
  25350. )END                                                                            
  25351. ./   ADD NAME=NNMPEXNG,SSI=01040050                                             
  25352. )ATTR                                                                           
  25353. /*                                                                   /*         
  25354. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25355. /*                                                                   /*         
  25356. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25357. /* including the implied warranties of merchantability and fitness,  /*         
  25358. /* are expressly denied.                                             /*         
  25359. /*                                                                   /*         
  25360. /* Provided this copyright notice is included, this software may     /*         
  25361. /* be freely distributed and not offered for sale.                   /*         
  25362. /*                                                                   /*         
  25363. /* Changes or modifications may be made and used only by the maker   /*         
  25364. /* of same, and not further distributed.  Such modifications should  /*         
  25365. /* be mailed to the author for consideration for addition to the     /*         
  25366. /* software and incorporation in subsequent releases.                /*         
  25367. /*                                                                   /*         
  25368.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25369. )BODY WINDOW(77,14)                                                             
  25370. +                                                                               
  25371. %Command ===>^ZCMD                                                              
  25372. +                                                                               
  25373. +Save to data set ===>_NNEXDSN                                                  
  25374.                                                                                 
  25375. +(Note: Data set will be RECFM=VB, LRECL=259, BLKSIZE=6233.)                    
  25376.                                                                                 
  25377. +Append to end of data set?   ===>_Z  +                                         
  25378. +Blank line after separator?  ===>_Z  +                                         
  25379. +Separator line between articles (append mode only...blank for none):           
  25380. +>^Z                                                                       +<   
  25381.                                                                                 
  25382. +Press%&END (END)+to cancel the extract request.                                
  25383. )INIT                                                                           
  25384.  .HELP = TNNM                                                                   
  25385.  .ZVARS = '(NNEXAPP NNEXBLK NNEXSEP)'                                           
  25386.  .CURSOR = NNEXDSN                                                              
  25387.  &ZWINTTL = 'Extract newsgroup listing'                                         
  25388.  &END = PFK(END)                                                                
  25389.  &ZCMD = &Z                                                                     
  25390.  VGET (NNEXDSN NNEXAPP NNEXBLK NNEXSEP) PROFILE                                 
  25391.  &NNEXAPP = TRANS(&NNEXAPP Y,YES N,NO ' ',NO)                                   
  25392.  &NNEXBLK = TRANS(&NNEXBLK Y,YES N,NO ' ',NO)                                   
  25393. )PROC                                                                           
  25394.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25395.  VER(&NNEXDSN,NB,DSNAME)                                                        
  25396.  &NNEXAPP = TRUNC(&NNEXAPP,1)                                                   
  25397.  VER(&NNEXAPP,NB,LIST,Y,N)                                                      
  25398.  &NNEXBLK = TRUNC(&NNEXBLK,1)                                                   
  25399.  VER(&NNEXBLK,NB,LIST,Y,N)                                                      
  25400.  VPUT (NNEXDSN NNEXAPP NNEXBLK NNEXSEP) PROFILE                                 
  25401. )END                                                                            
  25402. ./   ADD NAME=NNMPEXNP,SSI=01060057                                             
  25403. )ATTR                                                                           
  25404. /*                                                                   /*         
  25405. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25406. /*                                                                   /*         
  25407. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25408. /* including the implied warranties of merchantability and fitness,  /*         
  25409. /* are expressly denied.                                             /*         
  25410. /*                                                                   /*         
  25411. /* Provided this copyright notice is included, this software may     /*         
  25412. /* be freely distributed and not offered for sale.                   /*         
  25413. /*                                                                   /*         
  25414. /* Changes or modifications may be made and used only by the maker   /*         
  25415. /* of same, and not further distributed.  Such modifications should  /*         
  25416. /* be mailed to the author for consideration for addition to the     /*         
  25417. /* software and incorporation in subsequent releases.                /*         
  25418. /*                                                                   /*         
  25419.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25420. )BODY EXPAND(``) WINDOW(77,14)                                                  
  25421. +                                                                               
  25422. %Command ===>^ZCMD                                                              
  25423. +                                                                               
  25424. +Data set name%===>_NNEXPDS                                                     
  25425. +Member prefix%===>_NNEXPMP + (article number appended - default is%#+)         
  25426.                                                                                 
  25427. +Note: The dataset must be a PDS (old or new) with RECFM=VB and LRECL=259.      
  25428.                                                                                 
  25429. +Expand tab characters?      %===>_Z  +                                         
  25430.                                                                                 
  25431. +From article number%===>_NNEXAN1      + (blank for first article in table)     
  25432. +To   article number%===>_NNEXAN2      + (blank for last article in table)      
  25433.                                                                                 
  25434. +Press%&END (END)+to cancel the extract request.                                
  25435. )INIT                                                                           
  25436.  .HELP = TNNM                                                                   
  25437.  .ZVARS = '(NNEXTAB)'                                                           
  25438.  .CURSOR = ZCMD                                                                 
  25439.  &ZWINTTL = 'Log text of articles in &NNGROUP to PDS members'                   
  25440.  &NUMBER = ' &NNTNUM: '                                                         
  25441.  &END = PFK(END)                                                                
  25442.  &ZCMD = &Z                                                                     
  25443.  VGET (NNEXPDS NNEXPMP NNEXTAB) PROFILE                                         
  25444.  &NNEXTAB = TRANS(&NNEXTAB Y,YES N,NO ' ',NO)                                   
  25445.  IF (&NNEXPMP = &Z) &NNEXPMP = '#'                                              
  25446.  &NNEXAN1 = &Z                                                                  
  25447.  &NNEXAN2 = &Z                                                                  
  25448. )PROC                                                                           
  25449.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25450.  &NNEXTAB = TRUNC(&NNEXTAB,1)                                                   
  25451.  VER(&NNEXTAB,NB,LIST,Y,N)                                                      
  25452.  VER(&NNEXPDS,NB,DSNAME)                                                        
  25453.  &TEMP1 = TRUNC(&NNEXPDS,1)                                                     
  25454.  &TEMP2 = .TRAIL                                                                
  25455.  IF (&TEMP1 = '''')                                                             
  25456.   &NNEXDSN = TRUNC(&TEMP2,'''')                                                 
  25457.  ELSE                                                                           
  25458.   &NNEXDSN = '&ZPREFIX..&NNEXPDS'                                               
  25459.   VER(&NNEXPMP,NB,NAME)                                                         
  25460.  VER(&NNEXAN1,NUM)                                                              
  25461.  VER(&NNEXAN2,NUM)                                                              
  25462.  VPUT (NNEXPDS NNEXPMP NNEXTAB) PROFILE                                         
  25463. )END                                                                            
  25464. ./   ADD NAME=NNMPEXNS,SSI=01050005                                             
  25465. )ATTR                                                                           
  25466. /*                                                                   /*         
  25467. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25468. /*                                                                   /*         
  25469. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25470. /* including the implied warranties of merchantability and fitness,  /*         
  25471. /* are expressly denied.                                             /*         
  25472. /*                                                                   /*         
  25473. /* Provided this copyright notice is included, this software may     /*         
  25474. /* be freely distributed and not offered for sale.                   /*         
  25475. /*                                                                   /*         
  25476. /* Changes or modifications may be made and used only by the maker   /*         
  25477. /* of same, and not further distributed.  Such modifications should  /*         
  25478. /* be mailed to the author for consideration for addition to the     /*         
  25479. /* software and incorporation in subsequent releases.                /*         
  25480. /*                                                                   /*         
  25481.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25482. )BODY EXPAND(``) WINDOW(77,17)                                                  
  25483. +                                                                               
  25484. %Command ===>^ZCMD                                                              
  25485. +                                                                               
  25486. +Data set name%===>_NNEXSEQ                                                     
  25487. +(Note: Data set will be RECFM=VB, LRECL=259, BLKSIZE=6233.)                    
  25488. +                                                                               
  25489. +Expand tab characters?      %===>_Z  +                                         
  25490. +                                                                               
  25491. +Append to end of data set?  %===>_Z  +                                         
  25492. +Blank line after separator? %===>_Z  +                                         
  25493. +Separator line before each article (leave blank for none):                     
  25494. +>^Z                                                                       +<   
  25495.                                                                                 
  25496. +From article number%===>_NNEXAN1      + (blank for first article in table)     
  25497. +To   article number%===>_NNEXAN2      + (blank for last article in table)      
  25498.                                                                                 
  25499. +Press%&END (END)+to cancel the extract request.                                
  25500. )INIT                                                                           
  25501.  .HELP = TNNM                                                                   
  25502.  .ZVARS = '(NNEXTAB NNEXAPP NNEXBLK NNEXSEP)'                                   
  25503.  .CURSOR = ZCMD                                                                 
  25504.  &ZWINTTL = 'Log text of articles in &NNGROUP to sequential file'               
  25505.  &NUMBER = ' &NNTNUM: '                                                         
  25506.  &END = PFK(END)                                                                
  25507.  &ZCMD = &Z                                                                     
  25508.  VGET (NNEXSEQ NNEXTAB NNEXAPP NNEXBLK NNEXSEP) PROFILE                         
  25509.  &NNEXTAB = TRANS(&NNEXTAB Y,YES N,NO ' ',NO)                                   
  25510.  &NNEXAPP = TRANS(&NNEXAPP Y,YES N,NO ' ',NO)                                   
  25511.  &NNEXBLK = TRANS(&NNEXBLK Y,YES N,NO ' ',NO)                                   
  25512.  &NNEXAN1 = &Z                                                                  
  25513.  &NNEXAN2 = &Z                                                                  
  25514. )PROC                                                                           
  25515.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25516.  VER(&NNEXSEQ,NB,DSNAME)                                                        
  25517.  &NNEXDSN = &NNEXSEQ                                                            
  25518.  &NNEXTAB = TRUNC(&NNEXTAB,1)                                                   
  25519.  VER(&NNEXTAB,NB,LIST,Y,N)                                                      
  25520.  &NNEXAPP = TRUNC(&NNEXAPP,1)                                                   
  25521.  VER(&NNEXAPP,NB,LIST,Y,N)                                                      
  25522.  &NNEXBLK = TRUNC(&NNEXBLK,1)                                                   
  25523.  VER(&NNEXBLK,NB,LIST,Y,N)                                                      
  25524.  VER(&NNEXAN1,NUM)                                                              
  25525.  VER(&NNEXAN2,NUM)                                                              
  25526.  VPUT (NNEXSEQ NNEXTAB NNEXAPP NNEXBLK NNEXSEP) PROFILE                         
  25527. )END                                                                            
  25528. ./   ADD NAME=NNMPEXNT,SSI=01060013                                             
  25529. )ATTR                                                                           
  25530. /*                                                                   /*         
  25531. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25532. /*                                                                   /*         
  25533. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25534. /* including the implied warranties of merchantability and fitness,  /*         
  25535. /* are expressly denied.                                             /*         
  25536. /*                                                                   /*         
  25537. /* Provided this copyright notice is included, this software may     /*         
  25538. /* be freely distributed and not offered for sale.                   /*         
  25539. /*                                                                   /*         
  25540. /* Changes or modifications may be made and used only by the maker   /*         
  25541. /* of same, and not further distributed.  Such modifications should  /*         
  25542. /* be mailed to the author for consideration for addition to the     /*         
  25543. /* software and incorporation in subsequent releases.                /*         
  25544. /*                                                                   /*         
  25545.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25546. )BODY WINDOW(77,10)                                                             
  25547. +                                                                               
  25548. %Command ===>^ZCMD                                                              
  25549. +                                                                               
  25550. +Move cursor to choice (or type%S+next to choice) and press%ENTER+to select:    
  25551. +                                                                               
  25552. _A%1+- List%titles+of articles in table                                         
  25553. _B%2+- Log %text  +of articles to%sequential file+                              
  25554. _C%3+- Log %text  +of articles to%members of PDS+                               
  25555. +                                                                               
  25556. +Press%&END (END)+to cancel the extract request.                                
  25557. )INIT                                                                           
  25558.  .HELP = TNNM                                                                   
  25559.  .CURSOR = ZCMD                                                                 
  25560.  &ZWINTTL = 'Extract news articles - titles or text'                            
  25561.  &END = PFK(END)                                                                
  25562.  &ZCMD = &Z                                                                     
  25563.  &A = &Z                                                                        
  25564.  &B = &Z                                                                        
  25565.  &C = &Z                                                                        
  25566. )PROC                                                                           
  25567.  VER(&ZCMD,LIST,1,2,3)                                                          
  25568.  IF (&ZCMD ^= &Z)                                                               
  25569.   &NNCHOICE = TRANS(&ZCMD 1 1 2 2 3 3 * ?)                                      
  25570.  ELSE                                                                           
  25571.   &TEMP = '&A/&B/&C'                                                            
  25572.   IF (&TEMP = '//')                                                             
  25573.    &NNCHOICE = TRANS(.CURSOR A 1 B 2 C 3 * ?)                                   
  25574.   ELSE                                                                          
  25575.    &NNCHOICE = TRANS(&TEMP  'S//' 1                                             
  25576.                             '1//' 1                                             
  25577.                             '/S/' 2                                             
  25578.                             '/2/' 2                                             
  25579.                             '//S' 3                                             
  25580.                             '//3' 3                                             
  25581.                                * ?                                              
  25582.                    )                                                            
  25583. )END                                                                            
  25584. ./   ADD NAME=NNMPEXN1,SSI=01030021                                             
  25585. )ATTR                                                                           
  25586. /*                                                                   /*         
  25587. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25588. /*                                                                   /*         
  25589. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25590. /* including the implied warranties of merchantability and fitness,  /*         
  25591. /* are expressly denied.                                             /*         
  25592. /*                                                                   /*         
  25593. /* Provided this copyright notice is included, this software may     /*         
  25594. /* be freely distributed and not offered for sale.                   /*         
  25595. /*                                                                   /*         
  25596. /* Changes or modifications may be made and used only by the maker   /*         
  25597. /* of same, and not further distributed.  Such modifications should  /*         
  25598. /* be mailed to the author for consideration for addition to the     /*         
  25599. /* software and incorporation in subsequent releases.                /*         
  25600. /*                                                                   /*         
  25601.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25602. )BODY WINDOW(77,14)                                                             
  25603. +                                                                               
  25604. %Command ===>^ZCMD                                                              
  25605. +                                                                               
  25606. +Save to data set ===>_NNEXDSN                                                  
  25607.                                                                                 
  25608. +(Note: Data set will be RECFM=VB, LRECL=259, BLKSIZE=6233.)                    
  25609.                                                                                 
  25610. +Append to end of data set?   ===>_Z  +                                         
  25611. +Blank line after separator?  ===>_Z  +                                         
  25612. +Separator line between articles (append mode only...blank for none):           
  25613. +>^Z                                                                       +<   
  25614.                                                                                 
  25615. +Press%&END (END)+to cancel the extract request.                                
  25616. )INIT                                                                           
  25617.  .HELP = TNNM                                                                   
  25618.  .ZVARS = '(NNEXAPP NNEXBLK NNEXSEP)'                                           
  25619.  .CURSOR = NNEXDSN                                                              
  25620.  &ZWINTTL = 'Extract news article listing'                                      
  25621.  &END = PFK(END)                                                                
  25622.  &ZCMD = &Z                                                                     
  25623.  VGET (NNEXDSN NNEXAPP NNEXBLK NNEXSEP) PROFILE                                 
  25624.  &NNEXAPP = TRANS(&NNEXAPP Y,YES N,NO ' ',NO)                                   
  25625.  &NNEXBLK = TRANS(&NNEXBLK Y,YES N,NO ' ',NO)                                   
  25626. )PROC                                                                           
  25627.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25628.  VER(&NNEXDSN,NB,DSNAME)                                                        
  25629.  &NNEXAPP = TRUNC(&NNEXAPP,1)                                                   
  25630.  VER(&NNEXAPP,NB,LIST,Y,N)                                                      
  25631.  &NNEXBLK = TRUNC(&NNEXBLK,1)                                                   
  25632.  VER(&NNEXBLK,NB,LIST,Y,N)                                                      
  25633.  VPUT (NNEXDSN NNEXAPP NNEXBLK NNEXSEP) PROFILE                                 
  25634. )END                                                                            
  25635. ./   ADD NAME=NNMPEXOW,SSI=01020028                                             
  25636. )ATTR                                                                           
  25637. /*                                                                   /*         
  25638. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25639. /*                                                                   /*         
  25640. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25641. /* including the implied warranties of merchantability and fitness,  /*         
  25642. /* are expressly denied.                                             /*         
  25643. /*                                                                   /*         
  25644. /* Provided this copyright notice is included, this software may     /*         
  25645. /* be freely distributed and not offered for sale.                   /*         
  25646. /*                                                                   /*         
  25647. /* Changes or modifications may be made and used only by the maker   /*         
  25648. /* of same, and not further distributed.  Such modifications should  /*         
  25649. /* be mailed to the author for consideration for addition to the     /*         
  25650. /* software and incorporation in subsequent releases.                /*         
  25651. /*                                                                   /*         
  25652.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25653. )BODY WINDOW(58,10)                                                             
  25654. +                                                                               
  25655. %Command ===>^ZCMD                                                              
  25656. +                                                                               
  25657. +Dataset already exists:                                                        
  25658. +                                                                               
  25659. %&NNEXDSN                                                                       
  25660. +                                                                               
  25661. +Press%ENTER+to%&ACTION                                                         
  25662. +Press%&END (END)+to cancel the request.                                        
  25663. +                                                                               
  25664. )INIT                                                                           
  25665.  .HELP = TNNM                                                                   
  25666.  .ALARM = YES                                                                   
  25667.  &ZWINTTL = 'Extract To Existing Data Set'                                      
  25668.  &END = PFK(END)                                                                
  25669.  &APP = TRUNC(&NNEXAPP,1)                                                       
  25670.  IF (&APP = Y) &ACTION = 'append to the end of the data set.'                   
  25671.  ELSE          &ACTION = 'overwrite the current data set.'                      
  25672. )PROC                                                                           
  25673.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25674. )END                                                                            
  25675. ./   ADD NAME=NNMPEXPW,SSI=01020035                                             
  25676. )ATTR                                                                           
  25677. /*                                                                   /*         
  25678. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25679. /*                                                                   /*         
  25680. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25681. /* including the implied warranties of merchantability and fitness,  /*         
  25682. /* are expressly denied.                                             /*         
  25683. /*                                                                   /*         
  25684. /* Provided this copyright notice is included, this software may     /*         
  25685. /* be freely distributed and not offered for sale.                   /*         
  25686. /*                                                                   /*         
  25687. /* Changes or modifications may be made and used only by the maker   /*         
  25688. /* of same, and not further distributed.  Such modifications should  /*         
  25689. /* be mailed to the author for consideration for addition to the     /*         
  25690. /* software and incorporation in subsequent releases.                /*         
  25691. /*                                                                   /*         
  25692.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25693. )BODY WINDOW(58,13)                                                             
  25694. +                                                                               
  25695. %Command ===>^ZCMD                                                              
  25696. +                                                                               
  25697. +Partitioned dataset already exists:                                            
  25698. +                                                                               
  25699. %&NNEXDSN                                                                       
  25700. +                                                                               
  25701. +If member names are generated that match existing members                      
  25702. +of this PDS, they will be%overwritten.+                                        
  25703. +                                                                               
  25704. +Press%ENTER+to proceed to use this PDS.                                        
  25705. +Press%&END (END)+to cancel the request.                                        
  25706. +                                                                               
  25707. )INIT                                                                           
  25708.  .HELP = TNNM                                                                   
  25709.  .ALARM = YES                                                                   
  25710.  &ZWINTTL = 'Extract To Members of Existing PDS'                                
  25711.  &END = PFK(END)                                                                
  25712. )PROC                                                                           
  25713.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25714. )END                                                                            
  25715. ./   ADD NAME=NNMPGREG,SSI=01060042                                             
  25716. )ATTR                                                                           
  25717. /*                                                                   /*         
  25718. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25719. /*                                                                   /*         
  25720. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25721. /* including the implied warranties of merchantability and fitness,  /*         
  25722. /* are expressly denied.                                             /*         
  25723. /*                                                                   /*         
  25724. /* Provided this copyright notice is included, this software may     /*         
  25725. /* be freely distributed and not offered for sale.                   /*         
  25726. /*                                                                   /*         
  25727. /* Changes or modifications may be made and used only by the maker   /*         
  25728. /* of same, and not further distributed.  Such modifications should  /*         
  25729. /* be mailed to the author for consideration for addition to the     /*         
  25730. /* software and incorporation in subsequent releases.                /*         
  25731. /*                                                                   /*         
  25732.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25733. )BODY WINDOW(58,10)                                                             
  25734. +                                                                               
  25735. %Command ===>^ZCMD                                                              
  25736. +                                                                               
  25737. +Get current status of each newsgroup in your list?                             
  25738. +(If you answer YES, it will take longer to start up.)                          
  25739. +(If you answer NO, displayed status will be incomplete.)                       
  25740. +                                                                               
  25741. %===>_Z  +                                                                      
  25742.                                                                                 
  25743. +Press%&END (END)+to return to the previous panel.                              
  25744. )INIT                                                                           
  25745.  .HELP = TNNM                                                                   
  25746.  .ZVARS = '(NNRGANS)'                                                           
  25747.  .CURSOR = NNRGANS                                                              
  25748.  &ZWINTTL = ''                                                                  
  25749.  &END = PFK(END)                                                                
  25750.  &NNRGANS = Y                                                                   
  25751. )PROC                                                                           
  25752.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25753.  &NNRGANS = TRUNC(&NNRGANS,1)                                                   
  25754.  VER(&NNRGANS,NB,LIST,Y,N)                                                      
  25755. )END                                                                            
  25756. ./   ADD NAME=NNMPMALL,SSI=01010044                                             
  25757. )ATTR                                                                           
  25758. /*                                                                   /*         
  25759. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25760. /*                                                                   /*         
  25761. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25762. /* including the implied warranties of merchantability and fitness,  /*         
  25763. /* are expressly denied.                                             /*         
  25764. /*                                                                   /*         
  25765. /* Provided this copyright notice is included, this software may     /*         
  25766. /* be freely distributed and not offered for sale.                   /*         
  25767. /*                                                                   /*         
  25768. /* Changes or modifications may be made and used only by the maker   /*         
  25769. /* of same, and not further distributed.  Such modifications should  /*         
  25770. /* be mailed to the author for consideration for addition to the     /*         
  25771. /* software and incorporation in subsequent releases.                /*         
  25772. /*                                                                   /*         
  25773.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25774. )BODY WINDOW(76,14)                                                             
  25775. +                                                                               
  25776. %Command ===>^ZCMD                                                              
  25777. +                                                                               
  25778. +Newsgroup:%&NNGNAME                                                            
  25779. +                                                                               
  25780. +What exactly do you want to do?                                                
  25781. +                                                                               
  25782. _Z%*+Mark%all+articles in the newsgroup &NNMARK                                 
  25783. _Z%*+Mark%currently displayed+articles &NNMARK                                  
  25784. _Z%*+Cancel this request and return to previous panel                           
  25785.                                                                                 
  25786. +Move cursor to choice (or type%S+next to choice) and press%ENTER+to do it.     
  25787. +                                                                               
  25788. +Press%&END (END)+to cancel the request.                                        
  25789. )INIT                                                                           
  25790.  .HELP = TNNM                                                                   
  25791.  .ZVARS = '(S1 S2 S3)'                                                          
  25792.  .CURSOR = ZCMD                                                                 
  25793.  &ZWINTTL = 'Confirm Marking All Articles in Newsgroup'                         
  25794.  &END = PFK(END)                                                                
  25795.  &ZCMD = &Z                                                                     
  25796.  &S1   = &Z                                                                     
  25797.  &S2   = &Z                                                                     
  25798.  &S3   = &Z                                                                     
  25799. )PROC                                                                           
  25800.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25801.  &TEMP = '&S1/&S2/&S3'                                                          
  25802.  IF (&TEMP = '//')                                                              
  25803.   &NNCHOICE = TRANS(.CURSOR S1 1 S2 2 S3 3 * ?)                                 
  25804.  ELSE                                                                           
  25805.   &NNCHOICE = TRANS(&TEMP  'S//' 1                                              
  25806.                            '1//' 1                                              
  25807.                            '/S/' 2                                              
  25808.                            '/2/' 2                                              
  25809.                            '//S' 3                                              
  25810.                            '//3' 3                                              
  25811.                                * ?                                              
  25812.                   )                                                             
  25813. )END                                                                            
  25814. ./   ADD NAME=NNMPMARK,SSI=01030048                                             
  25815. )ATTR                                                                           
  25816. /*                                                                   /*         
  25817. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25818. /*                                                                   /*         
  25819. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25820. /* including the implied warranties of merchantability and fitness,  /*         
  25821. /* are expressly denied.                                             /*         
  25822. /*                                                                   /*         
  25823. /* Provided this copyright notice is included, this software may     /*         
  25824. /* be freely distributed and not offered for sale.                   /*         
  25825. /*                                                                   /*         
  25826. /* Changes or modifications may be made and used only by the maker   /*         
  25827. /* of same, and not further distributed.  Such modifications should  /*         
  25828. /* be mailed to the author for consideration for addition to the     /*         
  25829. /* software and incorporation in subsequent releases.                /*         
  25830. /*                                                                   /*         
  25831.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25832. )BODY WINDOW(58,10)                                                             
  25833. +                                                                               
  25834. %Command ===>^ZCMD                                                              
  25835. +                                                                               
  25836. +Newsgroup:%&NNGNAME                                                            
  25837. +                                                                               
  25838. +Be sure you really want to mark all articles%&NNMARK..                         
  25839. +                                                                               
  25840. +Press%ENTER+to proceed with marking all articles.                              
  25841. +                                                                               
  25842. +Press%&END (END)+to cancel the request.                                        
  25843. )INIT                                                                           
  25844.  .HELP = TNNM                                                                   
  25845.  &ZWINTTL = 'Confirm Marking All Articles in Newsgroup'                         
  25846.  &END = PFK(END)                                                                
  25847. )PROC                                                                           
  25848.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25849. )END                                                                            
  25850. ./   ADD NAME=NNMPOPT,SSI=01050056                                              
  25851. )ATTR                                                                           
  25852. /*                                                                   /*         
  25853. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25854. /*                                                                   /*         
  25855. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25856. /* including the implied warranties of merchantability and fitness,  /*         
  25857. /* are expressly denied.                                             /*         
  25858. /*                                                                   /*         
  25859. /* Provided this copyright notice is included, this software may     /*         
  25860. /* be freely distributed and not offered for sale.                   /*         
  25861. /*                                                                   /*         
  25862. /* Changes or modifications may be made and used only by the maker   /*         
  25863. /* of same, and not further distributed.  Such modifications should  /*         
  25864. /* be mailed to the author for consideration for addition to the     /*         
  25865. /* software and incorporation in subsequent releases.                /*         
  25866. /*                                                                   /*         
  25867.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25868. )BODY WINDOW(77,11)                                                             
  25869. +                                                                               
  25870. %Command ===>^ZCMD                                                              
  25871. +                                                                               
  25872. +Move cursor to choice (or type%S+next to choice) and press%ENTER+to select:    
  25873. +                                                                               
  25874. _Z%1+- RFC822 header display options                                            
  25875. _Z%2+- Article retrieval options                                                
  25876. _Z%3+- Table processing options                                                 
  25877. +                                                                               
  25878. +Press%&END (END)+to return to the previous panel.                              
  25879. )INIT                                                                           
  25880.  .HELP = TNNMOPT                                                                
  25881.  .ZVARS = '(S1 S2 S3)'                                                          
  25882.  .CURSOR = ZCMD                                                                 
  25883.  &ZWINTTL = 'Customize user options'                                            
  25884.  &END = PFK(END)                                                                
  25885.  &ZCMD = &Z                                                                     
  25886.  &S1   = &Z                                                                     
  25887.  &S2   = &Z                                                                     
  25888.  &S3   = &Z                                                                     
  25889. )PROC                                                                           
  25890.  IF (&ZCMD ^= &Z)                                                               
  25891.   &NNCHOICE = TRANS(&ZCMD 1 1 2 2 3 3 * ?)                                      
  25892.  ELSE                                                                           
  25893.   &TEMP = '&S1/&S2/&S3'                                                         
  25894.   IF (&TEMP = '//')                                                             
  25895.    &NNCHOICE = TRANS(.CURSOR S1 1 S2 2 S3 3 * ?)                                
  25896.   ELSE                                                                          
  25897.    &NNCHOICE = TRANS(&TEMP  'S//' 1                                             
  25898.                             '1//' 1                                             
  25899.                             '/S/' 2                                             
  25900.                             '/2/' 2                                             
  25901.                             '//S' 3                                             
  25902.                             '//3' 3                                             
  25903.                                 * ?                                             
  25904.                    )                                                            
  25905. )END                                                                            
  25906. ./   ADD NAME=NNMQMAIL,SSI=01080000                                             
  25907. )ATTR                                                                           
  25908. /*                                                                   /*         
  25909. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25910. /*                                                                   /*         
  25911. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25912. /* including the implied warranties of merchantability and fitness,  /*         
  25913. /* are expressly denied.                                             /*         
  25914. /*                                                                   /*         
  25915. /* Provided this copyright notice is included, this software may     /*         
  25916. /* be freely distributed and not offered for sale.                   /*         
  25917. /*                                                                   /*         
  25918. /* Changes or modifications may be made and used only by the maker   /*         
  25919. /* of same, and not further distributed.  Such modifications should  /*         
  25920. /* be mailed to the author for consideration for addition to the     /*         
  25921. /* software and incorporation in subsequent releases.                /*         
  25922. /*                                                                   /*         
  25923.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25924. )BODY EXPAND(``)                                                                
  25925. -`-`- Send a mail message or reply -`-`-                                        
  25926. %Command ===>^ZCMD                                                              
  25927. +                                                                               
  25928. %Note:+This sends private mail to the individual sender named below.            
  25929.       +To transmit to the newsgroup, use the%POST+command, or use               
  25930.       +the%F (FOLLOWUP)+selection code.+                                        
  25931. +                                                                               
  25932. +&HEADING                                                                       
  25933.                                                                                 
  25934. %Required Header Fields+                                                        
  25935.                                                                                 
  25936. +Mail to ===>^NNMAILTO                                                          
  25937. +Subject ===>^NNMAILSJ                                                          
  25938.                                                                                 
  25939. %Optional Header Fields+                                                        
  25940.                                                                                 
  25941. +Reply to ==>^NNMAILRT                                                          
  25942.                                                                                 
  25943. +Your human name ==>^NNMAILFR                                                   
  25944. +Signature file  ==>_NNMAILSF                                                   
  25945. +Edit profile    ==>_NNEDPROF+                                                  
  25946.                                                                                 
  25947. +Press%ENTER+to proceed to the editor to compose the message.                   
  25948. +Press%&END (END)+to cancel the mailing request.                                
  25949. )INIT                                                                           
  25950.  .HELP = TNNM                                                                   
  25951.  IF (&NNMAILOT = &Z) &HEADING = 'New mail message'                              
  25952.  ELSE                &HEADING = 'Reply to message from &NNMAILOT'               
  25953.  IF (&NNMAILTO = &Z) .CURSOR = NNMAILTO                                         
  25954.  ELSE                .CURSOR = NNMAILSJ                                         
  25955.  &ZWINTTL = 'Send a mail message or reply'                                      
  25956.  &END = PFK(END)                                                                
  25957.  &ZCMD = &Z                                                                     
  25958.  IF (&NNEDPROF = &Z) &NNEDPROF = TEXT                                           
  25959.  /* IF (&NNMAILSF = &Z) &NNMAILSF = &NNPOSTSF */                                
  25960. )PROC                                                                           
  25961.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  25962.  VER(&NNMAILTO,NB)                                                              
  25963.  VER(&NNMAILSJ,NB)                                                              
  25964.  VER(&NNMAILSF,DSNAME)                                                          
  25965.  VER(&NNEDPROF,NAME)                                                            
  25966.  IF (&NNEDPROF = &Z) &NNEDPROF = TEXT                                           
  25967.  VPUT (NNMAILRT NNMAILFR NNMAILSF NNEDPROF) PROFILE                             
  25968. )END                                                                            
  25969. ./   ADD NAME=NNMQPOST,SSI=01040000                                             
  25970. )ATTR                                                                           
  25971. /*                                                                   /*         
  25972. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  25973. /*                                                                   /*         
  25974. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  25975. /* including the implied warranties of merchantability and fitness,  /*         
  25976. /* are expressly denied.                                             /*         
  25977. /*                                                                   /*         
  25978. /* Provided this copyright notice is included, this software may     /*         
  25979. /* be freely distributed and not offered for sale.                   /*         
  25980. /*                                                                   /*         
  25981. /* Changes or modifications may be made and used only by the maker   /*         
  25982. /* of same, and not further distributed.  Such modifications should  /*         
  25983. /* be mailed to the author for consideration for addition to the     /*         
  25984. /* software and incorporation in subsequent releases.                /*         
  25985. /*                                                                   /*         
  25986.        ^   TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                        
  25987. /*                                                                   /*         
  25988. /* There seems to be some kind of bug in ISPF 3.3.  Substitution of  /*         
  25989. /* variables is not done before the first input field, so I could    /*         
  25990. /* not put the panel heading where I wanted it. ???                  /*         
  25991. /*                                                                   /*         
  25992. )BODY EXPAND(``)                                                                
  25993.  -`-`- Post to news server -`-`-                                                
  25994. %Command ===>^ZCMD                                                              
  25995.                                                                                 
  25996. %Note:+The fate of a posted news article is determined by the%news server+      
  25997.       %(&NNSERVER).                                                             
  25998.                                                                                 
  25999. +Posting:  &HEADING                                                             
  26000.                                                                                 
  26001. %Required Header Fields+                                                        
  26002.                                                                                 
  26003. +Newsgroups  ===>^NNPOSTNG                                                      
  26004. +Subject     ===>^NNPOSTSJ                                                      
  26005.                                                                                 
  26006. %Optional Header Fields+                                                        
  26007.                                                                                 
  26008. +Reply To     ==>^NNPOSTRT                                                      
  26009. +Followup To  ==>^NNPOSTFO                                                      
  26010.                                                                                 
  26011. +Your human name ==>^NNPOSTFR                                                   
  26012. +Signature file  ==>_NNPOSTSF                                                   
  26013. +Edit profile    ==>_NNEDPROF+                                                  
  26014.                                                                                 
  26015. +Press%ENTER+to proceed to the editor to compose the article.                   
  26016. +Press%&END (END)+to cancel the posting request.                                
  26017. )INIT                                                                           
  26018.  .HELP = TNNM                                                                   
  26019.  IF (&NNPOSTHA = &Z)                                                            
  26020.   &HEADING = 'New Article'                                                      
  26021.  ELSE                                                                           
  26022.   &HEADING = 'Followup to Article &NNPOSTHA in group &NNPOSTHG'                 
  26023.  IF (&NNPOSTNG = &Z) .CURSOR = NNPOSTNG                                         
  26024.  ELSE                .CURSOR = NNPOSTSJ                                         
  26025.  &END = PFK(END)                                                                
  26026.  &ZCMD = &Z                                                                     
  26027.  IF (&NNEDPROF = &Z) &NNEDPROF = TEXT                                           
  26028.  /* IF (&NNPOSTSF = &Z) &NNPOSTSF = &NNMAILSF */                                
  26029. )PROC                                                                           
  26030.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  26031.  VER(&NNPOSTNG,NB)                                                              
  26032.  VER(&NNPOSTSJ,NB)                                                              
  26033.  VER(&NNPOSTSF,DSNAME)                                                          
  26034.  VER(&NNEDPROF,NAME)                                                            
  26035.  IF (&NNEDPROF = &Z) &NNEDPROF = TEXT                                           
  26036.  VPUT (NNPOSTRT NNPOSTFR NNPOSTSF NNEDPROF) PROFILE                             
  26037. )END                                                                            
  26038. ./   ADD NAME=NNMRCERR,SSI=01050000                                             
  26039. )ATTR                                                                           
  26040. /*                                                                   /*         
  26041. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26042. /*                                                                   /*         
  26043. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26044. /* including the implied warranties of merchantability and fitness,  /*         
  26045. /* are expressly denied.                                             /*         
  26046. /*                                                                   /*         
  26047. /* Provided this copyright notice is included, this software may     /*         
  26048. /* be freely distributed and not offered for sale.                   /*         
  26049. /*                                                                   /*         
  26050. /* Changes or modifications may be made and used only by the maker   /*         
  26051. /* of same, and not further distributed.  Such modifications should  /*         
  26052. /* be mailed to the author for consideration for addition to the     /*         
  26053. /* software and incorporation in subsequent releases.                /*         
  26054. /*                                                                   /*         
  26055.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  26056.  @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)                                          
  26057.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  26058.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  26059.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  26060.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  26061.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  26062. )BODY EXPAND(``)                                                                
  26063. %-`-`-  MVS Network News Viewer -`-`-                                           
  26064. %COMMAND ===>_ZCMD                                                              
  26065. +                                                                               
  26066. %  ` `  *** ERROR ***  ` ` +                                                    
  26067. +                                                                               
  26068. % ` ` Unable to access the NEWSRC file, which is required. ` ` +                
  26069. +                                                                               
  26070. + ` ` This file must be allocated to DDname%NNNEWSRC. ` ` +                     
  26071. +                                                                               
  26072. + ` ` The News Viewer cannot continue. ` ` +                                    
  26073. +                                                                               
  26074. +                                                                               
  26075. + ` ` Press!ENTER+or!END+key to leave this panel. ` ` +                         
  26076. )INIT                                                                           
  26077.  .HELP = TNNM                                                                   
  26078. )PROC                                                                           
  26079.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  26080. )END                                                                            
  26081. ./   ADD NAME=NNMRFCH,SSI=01030029                                              
  26082. )ATTR                                                                           
  26083. /*                                                                   /*         
  26084. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26085. /*                                                                   /*         
  26086. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26087. /* including the implied warranties of merchantability and fitness,  /*         
  26088. /* are expressly denied.                                             /*         
  26089. /*                                                                   /*         
  26090. /* Provided this copyright notice is included, this software may     /*         
  26091. /* be freely distributed and not offered for sale.                   /*         
  26092. /*                                                                   /*         
  26093. /* Changes or modifications may be made and used only by the maker   /*         
  26094. /* of same, and not further distributed.  Such modifications should  /*         
  26095. /* be mailed to the author for consideration for addition to the     /*         
  26096. /* software and incorporation in subsequent releases.                /*         
  26097. /*                                                                   /*         
  26098.  ! TYPE(TEXT) INTENS(LOW)                                                       
  26099.  ? TYPE(TEXT) INTENS(LOW)                                                       
  26100.  { TYPE(TEXT) INTENS(LOW)                                                       
  26101.  } TYPE(TEXT) INTENS(LOW)                                                       
  26102. )BODY EXPAND(``)                                                                
  26103. %-`-`- NNMVS - RFC822 Header Viewing Options -`-`-                              
  26104. %Command ===>_ZCMD                                                              
  26105. +                                                                               
  26106. +The current RFC822 header viewing option is highlighted.                       
  26107. +Move cursor to choice (or type%S+next to choice) and press%ENTER+to change:    
  26108. +                                                                               
  26109. _A!Show all RFC822 headers                                                      
  26110. _B?Show all RFC822 headers except those in Exclude List                         
  26111. _C{Show the RFC822 headers in Include List only                                 
  26112. _D}Suppress RFC822 headers entirely                                             
  26113. +                                                                               
  26114. +Lists are header names separated by blanks.  Do%not+put%:+in header names.     
  26115. +                                                                               
  26116. %Include List ==>_NNRFCINC                                                      
  26117.                                                                                 
  26118.                                                                                 
  26119. %Exclude List ==>_NNRFCEXC                                                      
  26120.                                                                                 
  26121.                                                                                 
  26122. +Press%ENTER+to change options.  Press%&END+(or type%END+command) when done.    
  26123. )INIT                                                                           
  26124.  .HELP = TNNMOPT                                                                
  26125.  .CURSOR = ZCMD                                                                 
  26126.  &END = PFK(END)                                                                
  26127.  &ZCMD = &Z                                                                     
  26128.  &A = &Z                                                                        
  26129.  &B = &Z                                                                        
  26130.  &C = &Z                                                                        
  26131.  &D = &Z                                                                        
  26132.  VGET (NNRFCOPT NNRFCINC NNRFCEXC) PROFILE                                      
  26133.  IF (&NNRFCOPT = &Z) &NNRFCOPT = A                                              
  26134.  IF (&NNRFCOPT = A) .ATTRCHAR(!) = 'INTENS(HIGH)'                               
  26135.  IF (&NNRFCOPT = B) .ATTRCHAR(?) = 'INTENS(HIGH)'                               
  26136.  IF (&NNRFCOPT = C) .ATTRCHAR({) = 'INTENS(HIGH)'                               
  26137.  IF (&NNRFCOPT = D) .ATTRCHAR(}) = 'INTENS(HIGH)'                               
  26138.  IF (&NNRFCOPT = B) .ATTR(NNRFCEXC) = 'INTENS(HIGH)'                            
  26139.  ELSE               .ATTR(NNRFCEXC) = 'INTENS(LOW)'                             
  26140.  IF (&NNRFCOPT = C) .ATTR(NNRFCINC) = 'INTENS(HIGH)'                            
  26141.  ELSE               .ATTR(NNRFCINC) = 'INTENS(LOW)'                             
  26142. )PROC                                                                           
  26143.  IF (&ZCMD ^= &Z) .MSG = ISPZ001                                                
  26144.  IF (.RESP = ENTER)                                                             
  26145.   &TEMP = '&A/&B/&C/&D'                                                         
  26146.   IF (&TEMP = '///')                                                            
  26147.    &NNCHOICE = TRANS(.CURSOR A A B B C C D D * ' ')                             
  26148.   ELSE                                                                          
  26149.    &NNCHOICE = TRANS(&TEMP  'S///' A                                            
  26150.                             '/S//' B                                            
  26151.                             '//S/' C                                            
  26152.                             '///S' D                                            
  26153.                                * ?  )                                           
  26154.   IF (&NNCHOICE = '?')                                                          
  26155.    &ZERRSM   = 'Invalid choice'                                                 
  26156.    &ZERRLM   = 'Make exactly one selection with the cursor or type only one S.' 
  26157.    &ZERRALRM = YES                                                              
  26158.    &ZERRHM   = '*'                                                              
  26159.    .MSG = ISRZ002                                                               
  26160.   ELSE                                                                          
  26161.    IF (&NNCHOICE ^= &Z)                                                         
  26162.     &NNRFCOPT = &NNCHOICE                                                       
  26163.   VPUT (NNRFCOPT NNRFCINC NNRFCEXC) PROFILE                                     
  26164. )END                                                                            
  26165. ./   ADD NAME=NNM0,SSI=01070048                                                 
  26166. )ATTR                                                                           
  26167. /*                                                                   /*         
  26168. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26169. /*                                                                   /*         
  26170. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26171. /* including the implied warranties of merchantability and fitness,  /*         
  26172. /* are expressly denied.                                             /*         
  26173. /*                                                                   /*         
  26174. /* Provided this copyright notice is included, this software may     /*         
  26175. /* be freely distributed and not offered for sale.                   /*         
  26176. /*                                                                   /*         
  26177. /* Changes or modifications may be made and used only by the maker   /*         
  26178. /* of same, and not further distributed.  Such modifications should  /*         
  26179. /* be mailed to the author for consideration for addition to the     /*         
  26180. /* software and incorporation in subsequent releases.                /*         
  26181. /*                                                                   /*         
  26182.  _ TYPE(INPUT) INTENS(HIGH) CAPS(OFF) JUST(LEFT)                                
  26183.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  26184.  @ TYPE(TEXT) INTENS(HIGH) COLOR(PINK)                                          
  26185.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  26186.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  26187.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  26188.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  26189.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  26190. )BODY EXPAND(``)                                                                
  26191. %-`-`-  MVS Network News Client: NNTP Native Protocol Mode  -`-`-               
  26192. %COMMAND ===>_ZCMD                                                              
  26193. +                                                                               
  26194. %NNTP command ===>_NNCMD                                                        
  26195. +                                                                               
  26196. +                                                                               
  26197. +Press!END+key to leave this menu.                                              
  26198. )INIT                                                                           
  26199.  .HELP = TNNM                                                                   
  26200.  .CURSOR = NNCMD                                                                
  26201.  &ZCMD = &Z                                                                     
  26202. )PROC                                                                           
  26203.  IF (&ZCMD ^= &Z) .MSG=ISPZ001                                                  
  26204. )END                                                                            
  26205. ./   ADD NAME=TNNM,SSI=01080002                                                 
  26206. )ATTR                                                                           
  26207. /*                                                                   /*         
  26208. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26209. /*                                                                   /*         
  26210. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  26211. /*                                                                   /*         
  26212. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26213. /* including the implied warranties of merchantability and fitness,  /*         
  26214. /* are expressly denied.                                             /*         
  26215. /*                                                                   /*         
  26216. /* Provided this copyright notice is included, this software may     /*         
  26217. /* be freely distributed and not offered for sale.                   /*         
  26218. /*                                                                   /*         
  26219. /* Changes or modifications may be made and used only by the maker   /*         
  26220. /* of same, and not further distributed.  Such modifications should  /*         
  26221. /* be mailed to the author for consideration for addition to the     /*         
  26222. /* software and incorporation in subsequent releases.                /*         
  26223. /*                                                                   /*         
  26224.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  26225.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  26226.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  26227.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  26228.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  26229.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  26230. )BODY EXPAND(``)                                                                
  26231. %TUTORIAL -`-`-  MVS Network News Viewer -`-`- TUTORIAL                         
  26232. %SELECTION ===>_ZCMD                                                           +
  26233. %                                                                               
  26234. +NNMVS is an NNTP (network news transfer protocol)%news client+that runs on the 
  26235.  IBM mainframe using ISPF services.  It retrieves news articles from an NNTP    
  26236. %news server+executing on a host machine elsewhere on your network.  You must   
  26237.  tell NNMVS where this news server is; it does not know otherwise.              
  26238.                                                                                 
  26239. +NNMVS remembers which articles you have read in a%"newsrc"+file, whose name    
  26240.  defaults to%&ZPREFIX..NEWSRC+.  If you are a new user, you use the%L+or%blank+ 
  26241. +option to build your NEWSRC file with a list retrieved from the server.  To    
  26242.  limit the list to your favorite newsgroups, you can register (subscribe to)    
  26243.  the ones you want while viewing the newsgroup list.  Once you have used NNMVS  
  26244.  and built a NEWSRC file, you may wish to use a different entry option to reduce
  26245.  startup time.  You can avoid retrieving the whole list by using the%R+option to
  26246.  view only%registered+(subscribed) newsgroups, or the%A+option to view%all+     
  26247.  newsgroups listed in your NEWSRC file.  You can use the%N+option to get a list 
  26248.  of newsgroups added since the last time you retrieved the newsgroup list (i.e. 
  26249.  used%L+or%N+).  The%G+option always goes directly to a specific newsgroup.     
  26250.                                                                                 
  26251. +Press%ENTER+to proceed with the tutorial, or enter a selection code:           
  26252.     %1+- Information on news servers                                            
  26253.     %2+- Information on NNTP, as described by RFC 1036                          
  26254. )INIT                                                                           
  26255. )PROC                                                                           
  26256.  &ZSEL = TRANS(&ZCMD,1,TNNMSERV,2,TNNMNNTP,*,?)                                 
  26257.  &ZCONT = TNNM001                                                               
  26258. )END                                                                            
  26259. ./   ADD NAME=TNNMB,SSI=01090025                                                
  26260. )ATTR                                                                           
  26261. /*                                                                   /*         
  26262. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26263. /*                                                                   /*         
  26264. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26265. /* including the implied warranties of merchantability and fitness,  /*         
  26266. /* are expressly denied.                                             /*         
  26267. /*                                                                   /*         
  26268. /* Provided this copyright notice is included, this software may     /*         
  26269. /* be freely distributed and not offered for sale.                   /*         
  26270. /*                                                                   /*         
  26271. /* Changes or modifications may be made and used only by the maker   /*         
  26272. /* of same, and not further distributed.  Such modifications should  /*         
  26273. /* be mailed to the author for consideration for addition to the     /*         
  26274. /* software and incorporation in subsequent releases.                /*         
  26275. /*                                                                   /*         
  26276.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  26277.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  26278.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  26279.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  26280.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  26281.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  26282. )BODY EXPAND(``)                                                                
  26283. %TUTORIAL -`-`-  MVS Network News Viewer -`-`- TUTORIAL                         
  26284. %SELECTION ===>_ZCMD                                                           +
  26285. %                                                                               
  26286. +When you select an article for viewing, you are placed in ISPF BROWSE.         
  26287. +From there, you can use all features of BROWSE, plus the following commands:   
  26288.                                                                                 
  26289. %NEXT+           - proceed directly to the next article in the newsgroup        
  26290. %NEXTSubj+or%NS+ - proceed directly to the next article on the same subject     
  26291. %NEXTT+   or%NT+ - proceed directly to the next article in the current table    
  26292. %NEXTU+   or%NU+ - proceed directly to the next unread article in the newsgroup 
  26293. %PREV+           - proceed directly to the previous article in the newsgroup    
  26294. %PREVSubj+or%PS+ - proceed directly to the previous article on the same subject 
  26295. %PREVT+   or%PT+ - proceed directly to the previous article in the current table
  26296. %PREVU+   or%PU+ - proceed directly to the previous unread article in the group 
  26297. %FIRSTSubj+or%FS+- proceed directly to first unread article on the same subject 
  26298. %NEWSUBJ+        - proceed directly to first unread article on different subject
  26299. %UNREAD+         - stop reading this article and mark it unread                 
  26300. %EXTRACT+or%EXT+ - copy the article into a data set                             
  26301. %OPTIONS+or%OPT+ - set user options (e.g. for display of message headers)       
  26302. %HEADERs+        - set display/extract options for message headers              
  26303. %FOLLOWUP+       - send a follow-up news article, news server permitting        
  26304. %REPLY+          - send private mail to the originator of the news article      
  26305. %QUIT+           - leave NNMVS, saving changes in NEWSRC file                   
  26306. +When browsing NNTP protocol displays, only the EXTRACT command is available.   
  26307. )INIT                                                                           
  26308. )PROC                                                                           
  26309.  &ZUP = TNNM001                                                                 
  26310. )END                                                                            
  26311.                                                                                 
  26312. Sorry, but I have no room for the following unless I make another tutorial:     
  26313.                                                                                 
  26314. +For NEXTSUBJ and PREVSUBJ, the subject is the subject of the current article   
  26315.  being displayed.  Case and RE:'s are ignored, and WAS: is taken into account.  
  26316. ./   ADD NAME=TNNMB1,SSI=01030048                                               
  26317. )ATTR                                                                           
  26318. /*                                                                   /*         
  26319. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26320. /*                                                                   /*         
  26321. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  26322. /*                                                                   /*         
  26323. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26324. /* including the implied warranties of merchantability and fitness,  /*         
  26325. /* are expressly denied.                                             /*         
  26326. /*                                                                   /*         
  26327. /* Provided this copyright notice is included, this software may     /*         
  26328. /* be freely distributed and not offered for sale.                   /*         
  26329. /*                                                                   /*         
  26330. /* Changes or modifications may be made and used only by the maker   /*         
  26331. /* of same, and not further distributed.  Such modifications should  /*         
  26332. /* be mailed to the author for consideration for addition to the     /*         
  26333. /* software and incorporation in subsequent releases.                /*         
  26334. /*                                                                   /*         
  26335.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  26336.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  26337.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  26338.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  26339.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  26340.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  26341. )BODY EXPAND(``)                                                                
  26342. %TUTORIAL -`-`-  MVS Network News Viewer -`-`- TUTORIAL                         
  26343. %SELECTION ===>_ZCMD                                                           +
  26344. +When you select an article for viewing, you are placed in ISPF BROWSE.         
  26345. +From there, you can use all features of BROWSE, plus the following commands:   
  26346. %NEXT+           - proceed directly to the next article in the newsgroup        
  26347. %NEXTSubj+ or%NS+- proceed directly to the next article on the same subject     
  26348. %NEXTT+    or%NT+- proceed directly to the next article in the current table    
  26349. %NEXTU+    or%NU+- proceed directly to the next unread article in the newsgroup 
  26350. %PREV+           - proceed directly to the previous article in the newsgroup    
  26351. %PREVSubj+ or%PS+- proceed directly to the previous article on the same subject 
  26352. %PREVT+    or%PT+- proceed directly to the previous article in the current table
  26353. %PREVU+    or%PU+- proceed directly to the previous unread article in the group 
  26354. %FIRSTSubj+or%FS+- proceed directly to first unread article on the same subject 
  26355. %LASTSubj +or%LS+- proceed directly to last unread article on the same subject  
  26356. %NEWSUBJ+        - proceed directly to first unread article on different subject
  26357. %SUBJECT+or%SUBJ+- display or change the current subject for subject searches   
  26358. %UNREAD+         - stop reading this article and mark it unread                 
  26359. %EXTRACT+or%EXT+ - copy the article into a data set                             
  26360. %OPTIONS+or%OPT+ - set user options (e.g. for display of message headers)       
  26361. %HEADERs+        - set display/extract options for message headers              
  26362. %FOLLOWUP+       - send a follow-up news article, news server permitting        
  26363. %REPLY+          - send private mail to the originator of the news article      
  26364. %QUIT+           - leave NNMVS, saving changes in NEWSRC file                   
  26365.                           %(continued on next page)+                            
  26366. )INIT                                                                           
  26367.  IF (&TNNMTHR = NNMBROBF) &ZUP = ISR10000                                       
  26368.  ELSE                     &ZUP = TNNM001                                        
  26369.  &ZCONT = TNNMB2                                                                
  26370. )PROC                                                                           
  26371. )END                                                                            
  26372. ./   ADD NAME=TNNMB2,SSI=01030038                                               
  26373. )ATTR                                                                           
  26374. /*                                                                   /*         
  26375. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26376. /*                                                                   /*         
  26377. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  26378. /*                                                                   /*         
  26379. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26380. /* including the implied warranties of merchantability and fitness,  /*         
  26381. /* are expressly denied.                                             /*         
  26382. /*                                                                   /*         
  26383. /* Provided this copyright notice is included, this software may     /*         
  26384. /* be freely distributed and not offered for sale.                   /*         
  26385. /*                                                                   /*         
  26386. /* Changes or modifications may be made and used only by the maker   /*         
  26387. /* of same, and not further distributed.  Such modifications should  /*         
  26388. /* be mailed to the author for consideration for addition to the     /*         
  26389. /* software and incorporation in subsequent releases.                /*         
  26390. /*                                                                   /*         
  26391.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  26392.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  26393.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  26394.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  26395.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  26396.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  26397. )BODY EXPAND(``)                                                                
  26398. %TUTORIAL -`-`-  MVS Network News Viewer -`-`- TUTORIAL                         
  26399. %SELECTION ===>_ZCMD                                                           +
  26400. %                                                                               
  26401. +For NEXTSUBJ, PREVSUBJ, FIRSTSUBJ and LASTSUBJ, the current subject is that    
  26402.  of the article being displayed.   Alphabetic case is ignored, and subjects     
  26403.  with RE: and WAS: wrappers are taken into account.                             
  26404.                                                                                 
  26405. +Note that NNTP protocol displays also use BROWSE mode.  When you are browsing  
  26406.  such output, the above commands are not available, except for EXTRACT and QUIT.
  26407.                                                                                 
  26408. )INIT                                                                           
  26409. )PROC                                                                           
  26410. )END                                                                            
  26411. ./   ADD NAME=TNNMG,SSI=010E0007                                                
  26412. )ATTR                                                                           
  26413. /*                                                                   /*         
  26414. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26415. /*                                                                   /*         
  26416. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26417. /* including the implied warranties of merchantability and fitness,  /*         
  26418. /* are expressly denied.                                             /*         
  26419. /*                                                                   /*         
  26420. /* Provided this copyright notice is included, this software may     /*         
  26421. /* be freely distributed and not offered for sale.                   /*         
  26422. /*                                                                   /*         
  26423. /* Changes or modifications may be made and used only by the maker   /*         
  26424. /* of same, and not further distributed.  Such modifications should  /*         
  26425. /* be mailed to the author for consideration for addition to the     /*         
  26426. /* software and incorporation in subsequent releases.                /*         
  26427. /*                                                                   /*         
  26428.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  26429.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  26430.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  26431.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  26432.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  26433.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  26434. )BODY EXPAND(``)                                                                
  26435. %TUTORIAL -`-`-  MVS Network News Viewer -`-`- TUTORIAL                         
  26436. %SELECTION ===>_ZCMD                                                           +
  26437. %                                                                               
  26438. +In the%newsgroup+display, you may type a code in front of a newsgroup name:    
  26439.                                                                                 
  26440.  %S+ - select:      display articles, initially just those you haven't seen yet 
  26441.  %N+ - new:         display unseen articles, removing seen ones from display    
  26442.  %A+ - all:         display all articles, seen or unseen                        
  26443.  %R+ - register:    mark the newsgroup as one of your "subscribed" groups       
  26444.  %D+ - deregister:  remove the newsgroup from your "subscribed" list            
  26445.  %M+ - mark read:   tell the News Viewer you've seen everything in this group   
  26446.  %U+ - mark unread: tell the News Viewer you haven't seen anything in the group 
  26447.  %Q+ - query:       display newsgroup status (for debugging only)               
  26448.                                                                                 
  26449. +You may type one of the following commands on the newsgroup command line:      
  26450.                                                                                 
  26451.  %LOCATE+or%LOC+or%L+- position display at or near given newsgroup name         
  26452.  %EXTRACT+or%EXT+    - copy the current list into a data set                    
  26453.  %REGISTER+or%REG+   - switch display to registered newsgroups only             
  26454.  %ALL+               - switch display to all newsgroups                         
  26455.  %ORDER Alpha/List+  - order groups alphabetically or by server's active list   
  26456.  %FIND string option+- find NEXT, PREV, FIRST or LAST group containing "string" 
  26457.  %ONLY string       +- limit newsgroup display to groups containing "string"    
  26458. )INIT                                                                           
  26459. )PROC                                                                           
  26460.  &ZUP   = TNNM001                                                               
  26461.  &ZCONT = TNNMT                                                                 
  26462. )END                                                                            
  26463. ./   ADD NAME=TNNMNNTP,SSI=01050000                                             
  26464. )ATTR                                                                           
  26465. /*                                                                   /*         
  26466. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26467. /*                                                                   /*         
  26468. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26469. /* including the implied warranties of merchantability and fitness,  /*         
  26470. /* are expressly denied.                                             /*         
  26471. /*                                                                   /*         
  26472. /* Provided this copyright notice is included, this software may     /*         
  26473. /* be freely distributed and not offered for sale.                   /*         
  26474. /*                                                                   /*         
  26475. /* Changes or modifications may be made and used only by the maker   /*         
  26476. /* of same, and not further distributed.  Such modifications should  /*         
  26477. /* be mailed to the author for consideration for addition to the     /*         
  26478. /* software and incorporation in subsequent releases.                /*         
  26479. /*                                                                   /*         
  26480.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  26481.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  26482.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  26483.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  26484.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  26485.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  26486. )BODY EXPAND(``)                                                                
  26487. %TUTORIAL -`-`-  MVS Network News Viewer -`-`- TUTORIAL                         
  26488. %SELECTION ===>_ZCMD                                                           +
  26489. %                                                                               
  26490. % ` `  NNTP (Network News Transfer Protocol)  ` `                               
  26491. %                                                                               
  26492. +RFC 977, "A Proposed Standard for the Stream-Based Transmission of News",      
  26493.  is the document that describes the Network News Transfer Protocol.             
  26494.                                                                                 
  26495.  You may also wish to read:                                                     
  26496.                                                                                 
  26497.  RFC 1036, "Standard for Interchange of USENET Messages"                        
  26498.                                                                                 
  26499.  The%N+option from the main NNMVS menu, or the%NNTP+command from the            
  26500.  Newsgroup or Article display, allows you to communicate directly with          
  26501.  the NNTP server using the protocol language defined in RFC 977, subject        
  26502.  to the support provided by the news server to which you are connected.         
  26503.                                                                                 
  26504. )INIT                                                                           
  26505. )PROC                                                                           
  26506.  &ZUP = TNNM                                                                    
  26507. )END                                                                            
  26508. ./   ADD NAME=TNNMOPT,SSI=01020040                                              
  26509. )ATTR                                                                           
  26510. /*                                                                   /*         
  26511. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26512. /*                                                                   /*         
  26513. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  26514. /*                                                                   /*         
  26515. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26516. /* including the implied warranties of merchantability and fitness,  /*         
  26517. /* are expressly denied.                                             /*         
  26518. /*                                                                   /*         
  26519. /* Provided this copyright notice is included, this software may     /*         
  26520. /* be freely distributed and not offered for sale.                   /*         
  26521. /*                                                                   /*         
  26522. /* Changes or modifications may be made and used only by the maker   /*         
  26523. /* of same, and not further distributed.  Such modifications should  /*         
  26524. /* be mailed to the author for consideration for addition to the     /*         
  26525. /* software and incorporation in subsequent releases.                /*         
  26526. /*                                                                   /*         
  26527.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  26528.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  26529.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  26530.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  26531.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  26532.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  26533. )BODY EXPAND(``)                                                                
  26534. %TUTORIAL -`-`-  MVS Network News Viewer -`-`- TUTORIAL                         
  26535. %SELECTION ===>_ZCMD                                                           +
  26536. %                                                                               
  26537. % ` `  Options  ` `                                                             
  26538. %                                                                               
  26539. +The user options you set when you enter the OPTIONS command are remembered in  
  26540.  your ISPF profile, as is typical of ISPF dialogs.  This is in contrast to      
  26541.  newsgroup and article status information, which is stored in your NEWSRC file  
  26542.  and not in your ISPF profile.                                                  
  26543.                                                                                 
  26544.  The first set of options specifies handling of the message headers that appear 
  26545.  in all news articles.  You may specify whether you want all header lines to be 
  26546.  displayed, or just certain ones to be displayed, or certain ones NOT to be     
  26547.  displayed, or none to be displayed.  The setting affects article extraction    
  26548.  into files as well as viewing.                                                 
  26549.                                                                                 
  26550. +You may specify the frequency at which the News Viewer will update the screen  
  26551.  for long-running processes, such as retrieving articles from large newsgroups. 
  26552.                                                                                 
  26553.   %(continued on next page)+                                                    
  26554. )INIT                                                                           
  26555. )PROC                                                                           
  26556.  &ZUP = TNNM                                                                    
  26557.  &ZCONT = TNNMOPT2                                                              
  26558. )END                                                                            
  26559. ./   ADD NAME=TNNMOPT2,SSI=01020001                                             
  26560. )ATTR                                                                           
  26561. /*                                                                   /*         
  26562. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26563. /*                                                                   /*         
  26564. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  26565. /*                                                                   /*         
  26566. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26567. /* including the implied warranties of merchantability and fitness,  /*         
  26568. /* are expressly denied.                                             /*         
  26569. /*                                                                   /*         
  26570. /* Provided this copyright notice is included, this software may     /*         
  26571. /* be freely distributed and not offered for sale.                   /*         
  26572. /*                                                                   /*         
  26573. /* Changes or modifications may be made and used only by the maker   /*         
  26574. /* of same, and not further distributed.  Such modifications should  /*         
  26575. /* be mailed to the author for consideration for addition to the     /*         
  26576. /* software and incorporation in subsequent releases.                /*         
  26577. /*                                                                   /*         
  26578.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  26579.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  26580.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  26581.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  26582.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  26583.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  26584. )BODY EXPAND(``)                                                                
  26585. %TUTORIAL -`-`-  MVS Network News Viewer -`-`- TUTORIAL                         
  26586. %SELECTION ===>_ZCMD                                                           +
  26587. %                                                                               
  26588. % ` `  Options - Screen Update Frequency ` `                                    
  26589. %                                                                               
  26590. +You may specify the frequency at which the News Viewer will update the screen  
  26591.  for long-running processes.  These include:                                    
  26592.                                                                                 
  26593.    fetching the list of all newsgroups                                          
  26594.    fetching the headers for unread articles in a newsgroup                      
  26595.    fetching the current status of registered newsgroup                          
  26596.                                                                                 
  26597.  Specifying%ON+is the same as specifying a frequency of zero.  The initial      
  26598.  default is%OFF,+but you may want to set it to%ON+or a number to experiment.    
  26599.                                                                                 
  26600.  When you use the%L+or%blank+option to fetch the list of all newsgroups, since  
  26601.  the total number is not known, every newsgroup name will flash on the screen as
  26602.  it is read if the Update option is not%OFF.+ For slow terminals, this can      
  26603.  greatly slow down the News Viewer; you should always specify%OFF+for slow      
  26604.  terminals if you intend to do this.  While article titles are being fetched, if
  26605.  Update is%OFF,+nothing is displayed until all titles are retrieved.  Otherwise,
  26606.  a bar graph showing the progress will be displayed at the indicated interval;  
  26607.  if Update is%ON+(the same as zero), the bar graph will be updated as every     
  26608.  title is read.  An estimated time to completion will be displayed as well.     
  26609. )INIT                                                                           
  26610. )PROC                                                                           
  26611.  &ZUP = TNNM                                                                    
  26612. )END                                                                            
  26613. ./   ADD NAME=TNNMSERV,SSI=010A0000                                             
  26614. )ATTR                                                                           
  26615. /*                                                                   /*         
  26616. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26617. /*                                                                   /*         
  26618. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26619. /* including the implied warranties of merchantability and fitness,  /*         
  26620. /* are expressly denied.                                             /*         
  26621. /*                                                                   /*         
  26622. /* Provided this copyright notice is included, this software may     /*         
  26623. /* be freely distributed and not offered for sale.                   /*         
  26624. /*                                                                   /*         
  26625. /* Changes or modifications may be made and used only by the maker   /*         
  26626. /* of same, and not further distributed.  Such modifications should  /*         
  26627. /* be mailed to the author for consideration for addition to the     /*         
  26628. /* software and incorporation in subsequent releases.                /*         
  26629. /*                                                                   /*         
  26630.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  26631.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  26632.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  26633.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  26634.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  26635.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  26636. )BODY EXPAND(``)                                                                
  26637. %TUTORIAL -`-`-  MVS Network News Viewer -`-`- TUTORIAL                         
  26638. %SELECTION ===>_ZCMD                                                           +
  26639. %                                                                               
  26640. % ` `  News Servers  ` `                                                        
  26641. %                                                                               
  26642. +Ask your system administrator to tell you the hostname of the machine          
  26643.  where an available news server is running.  You may need to ask the            
  26644.  administrator of that machine to grant you permission to access it             
  26645.  from the MVS system where the News Viewer will be running.                     
  26646.                                                                                 
  26647. +If the host name is not recognized, you may specify an IP address              
  26648.  (four numbers separated by periods in the format nn.nn.nn.nn).                 
  26649. )INIT                                                                           
  26650. )PROC                                                                           
  26651.  &ZUP = TNNM                                                                    
  26652. )END                                                                            
  26653. ./   ADD NAME=TNNMT,SSI=01140007                                                
  26654. )ATTR                                                                           
  26655. /*                                                                   /*         
  26656. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26657. /*                                                                   /*         
  26658. /* SAS enhancements copyright (c) 1992 SAS Institute, Inc.           /*         
  26659. /*                                                                   /*         
  26660. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26661. /* including the implied warranties of merchantability and fitness,  /*         
  26662. /* are expressly denied.                                             /*         
  26663. /*                                                                   /*         
  26664. /* Provided this copyright notice is included, this software may     /*         
  26665. /* be freely distributed and not offered for sale.                   /*         
  26666. /*                                                                   /*         
  26667. /* Changes or modifications may be made and used only by the maker   /*         
  26668. /* of same, and not further distributed.  Such modifications should  /*         
  26669. /* be mailed to the author for consideration for addition to the     /*         
  26670. /* software and incorporation in subsequent releases.                /*         
  26671. /*                                                                   /*         
  26672.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  26673.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  26674.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  26675.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  26676.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  26677.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  26678. )BODY EXPAND(``)                                                                
  26679. %TUTORIAL -`-`-  MVS Network News Viewer -`-`- TUTORIAL                         
  26680. %SELECTION ===>_ZCMD                                                           +
  26681. +In the%article+display, you may type these codes in front of an article number:
  26682.                                                                                 
  26683.  %S+ - select:      view the article via ISPF BROWSE                            
  26684.  %E+ - extract:     copy the article into a data set                            
  26685.  %M+ - mark read:   tell the News Viewer you've already seen this article       
  26686.  %U+ - mark unread: tell the News Viewer you haven't seen this article          
  26687.  %F+ - followup:    send a follow-up news article, news server permitting       
  26688.  %R+ - reply:       send private mail to the originator of the news article     
  26689.  %Q+ - query:       display article status (for debugging only).                
  26690.  %C+ - cancel:      send article cancel request to server (author must be you)  
  26691.                                                                                 
  26692. +You may type one of the following commands on the article display command line:
  26693.                                                                                 
  26694. %LOCATE+or%LOC+or%L+  - position display at or near given article number        
  26695. %EXTRACT+or%EXT+      - copy titles or text of all articles into a data set     
  26696. %TITLES+or%TITLE+     - retrieve titles of all articles in table from the server
  26697. %QUERY+               - display newsgroup status (for debugging only)           
  26698. %FIND string option+  - find NEXT, PREV, FIRST or LAST article with "string"    
  26699. %ONLY string       +  - limit display to articles with "string" in the subject  
  26700. %MARKALL+or%UNMARKALL+- mark all articles in this newsgroup read or unread      
  26701. %SORT Subject/Number +- sort article display by subject or by article number    
  26702. )INIT                                                                           
  26703. )PROC                                                                           
  26704.  &ZUP   = TNNM001                                                               
  26705.  &TNNMTHR = &Z                                                                  
  26706.  &ZCONT = TNNMB1                                                                
  26707. )END                                                                            
  26708. ./   ADD NAME=TNNM001,SSI=010F0007                                              
  26709. )ATTR                                                                           
  26710. /*                                                                   /*         
  26711. /* Copyright (c) The Charles Stark Draper Laboratory, Inc., 1992     /*         
  26712. /*                                                                   /*         
  26713. /* This software is provided on an "AS IS" basis.  All warranties,   /*         
  26714. /* including the implied warranties of merchantability and fitness,  /*         
  26715. /* are expressly denied.                                             /*         
  26716. /*                                                                   /*         
  26717. /* Provided this copyright notice is included, this software may     /*         
  26718. /* be freely distributed and not offered for sale.                   /*         
  26719. /*                                                                   /*         
  26720. /* Changes or modifications may be made and used only by the maker   /*         
  26721. /* of same, and not further distributed.  Such modifications should  /*         
  26722. /* be mailed to the author for consideration for addition to the     /*         
  26723. /* software and incorporation in subsequent releases.                /*         
  26724. /*                                                                   /*         
  26725.  ^ TYPE(TEXT) INTENS(HIGH) COLOR(BLUE) HILITE(REVERSE)                          
  26726.  # TYPE(TEXT) INTENS(LOW)  COLOR(TURQ)                                          
  26727.  \ TYPE(TEXT) INTENS(HIGH) COLOR(YELLOW)                                        
  26728.  ! TYPE(TEXT) INTENS(HIGH) COLOR(RED)                                           
  26729.  $ TYPE(TEXT) INTENS(LOW)  COLOR(GREEN)                                         
  26730.  ~ TYPE(TEXT) INTENS(HIGH) COLOR(WHITE)                                         
  26731. )BODY EXPAND(``)                                                                
  26732. %TUTORIAL -`-`-  MVS Network News Viewer -`-`- TUTORIAL                         
  26733. %SELECTION ===>_ZCMD                                                           +
  26734. %                                                                               
  26735. +There are two kinds of displays created by the News Viewer:                    
  26736.                                                                                 
  26737. %   Newsgroups+ - which allows you to select newsgroups by name                 
  26738. %   Articles  + - which allows you to select articles by name                   
  26739.                                                                                 
  26740. +From either kind of display, the following commands are available:             
  26741.                                                                                 
  26742.  %OPTIONS+or%OPT+- set user options (e.g. for display of message headers).      
  26743.  %SAVE          +- checkpoint%newsrc+(otherwise, will not be updated until exit)
  26744.  %POST          +- compose a news article for sending, news server permitting.  
  26745.  %MAIL          +- compose a mail message for sending to an individual user.    
  26746.  %NNTP          +- enter native NNTP protocol mode.  For debugging only.        
  26747.  %TEST          +- enter C/370 test mode (INSPECT).                             
  26748.  %QUIT          +- leave NNMVS, saving changes in NEWSRC file                   
  26749. +Additional commands are available specific to the Newsgroup or Article display.
  26750.                                                                                 
  26751. +The following topics will be displayed next, or may be selected by number:     
  26752. %   1 + - The Newsgroup Display (Available Selection Codes and Commands)        
  26753. %   2 + - The Article Display   (Available Selection Codes and Commands)        
  26754. %   3 + - Specifying User Options                                               
  26755. )INIT                                                                           
  26756. )PROC                                                                           
  26757.  &ZSEL = TRANS(&ZCMD 1,TNNMG 2,TNNMT 3,TNNMOPT *,?)                             
  26758.  &ZUP = TNNM                                                                    
  26759. )END                                                                            
  26760. ./ ENDUP                                                                        
  26761. ?!                                                                              
  26762.